MySQL two independent tables whose join do not exist in third table - mysql

I have three tables A (Master), B (Master) and C (Transaction).
The combination of A.id and B.id exists in C.
I want that data of A where combination of A.id and B.id do not exist in table C.
I tried the following but get no rows selected.
SELECT A.* from A, B, C where A.id != C.id and B.id != C.id
I am not that good at creating queries.
Can someone please form a query for this?

SELECT *
FROM A
WHERE A.id NOT IN (
SELECT Aid FROM C)
Your question is a bit strange though, this query selects all the id's of A which are not in table C.

SELECT A.*, B.*
FROM A , B
WHERE A.id = B.id AND A.id NOT IN (SELECT Aid FROM C) AND B.id NOT IN (SELECT Bid FROM C)

SELECT * FROM A,C LEFT JOIN B ON B.id = A.id LEFT JOIN B ON B.id =
C.id WHERE A.id=C.id AND B.id IS NULL

Related

Group by Use Query if SQL LEFT JOIN is performed multiple times

I think it's impossible, but I'm asking if there's a good way.
There are A table / B table / C table.
The table was joined LEFT JOIN based on table A with FK called id of each table.
At this time, I would like to output the count(*) as B table rows and C table rows based on b.id(B_CNT) c.id(C_CNT)
SELECT
*
FROM
A
LEFT JOIN B ON A.ID = B.ID
LEFT JOIN C ON A.ID = C.ID (base query)
how could I count group by b.id and c.id?
You could try:
SELECT
COUNT(DISTINCT B.ID), COUNT(DISTINCT C.ID)
FROM A
LEFT JOIN B
ON A.ID = B.ID
LEFT JOIN C
ON A.ID = C.ID
(I couldn't quite understand from your question, but I'm making an assumption that you want the distinct count of "ID" from each table)
You can use a couple of scalar subqueries. For example:
select id,
(select count(*) from b where b.id = a.id) as b,
(select count(*) from c where c.id = a.id) as c
from a

SQL find children that have multiple parent records

I have a situation where we have inserted duplicated data into some tables.
Given the following database schema, I want to find all records with s_id and co_id combinations associated to more than 1 record from table A. The highlighted rows are the rows I'm looking for, based off of finding the duplicates I need to find the id's from table A associated to the duplicate records.
I'm able to group by s_id & co_id to determine potential duplicates, but because Table B is a 1:M, this isn't entirely accurate.
Select c.s_id, c.co_id, Count(*)
from c
INNER JOIN b on c.b_id = b.id
INNER JOIN a on a.id = b.a_id
Group By c.s_id, c.co_id
Having count(*) > 1;
I think you just want count(distinct):
Select c.s_id, c.co_id, Count(distinct a.id)
from c join
b
on c.b_id = b.id join
a
on a.id = b.a_id
Group By c.s_id, c.co_id
having count(distinct a.id) > 1;
Gordon's answer will get you the s_id and co_id values. If you need to trace those back to a then try this:
select distinct a.id
from
a inner join b on b.a_id = a.id inner join c on c.b_id = b.id inner join
(
select c.s_id, c.co_id
from a inner join b on b.a_id = a.id inner join c on c.b_id = b.id
group by c.s_id, c.co_id
having count(distinct a.id) > 1
) as dups
on dups.s_id = c.s_id and dups.co_id = s.co_id

Fix inefficient and difficult query

I have a query in my application that is performing poorly. I think it can be optimzed but my SQL skills are failing me. Here's the query in a sort of meta-sql:
SELECT A.Value, count(*)
FROM B
JOIN A ON B.A_ID = A.ID
JOIN C ON C.ID = B.C_ID
WHERE B.C_ID IN (
SELECT B.C_ID
FROM C
JOIN B ON B.C_ID = C.ID
JOIN A ON B.A_ID = A.ID
WHERE A.VALUE IN 'string literal'
)
GROUP BY A.VALUE
C is a table of vacancies, B is a table of properties of the vacancies and A is a table of property values. The tables have 1 to N relationships. We need to find a list of all other property values (and the number of times they occur) of vacancies that have a certain fixed property value related to it.
Please help in optimizing the query for efficiency.
Thanks in advance!
You don't need to join in C in either query, unless that is being used for filtering (that is, non matches are being filtered out). Try this:
SELECT A.Value, count(*)
FROM B JOIN
A
ON B.A_ID = A.ID
WHERE EXISTS (SELECT 1
FROM B b2 JOIN
A a2
ON b2.A_ID = a2.ID
WHERE a2.VALUE = 'string literal' AND b2.C_ID = b.C_ID
)
GROUP BY A.VALUE;

SQL LEFT JOIN only newest right column entry?

So I have two tables like this:
create table A
{
id int;
...
}
create table B
{
id int;
a_id int;
t timestamp;
...
}
A is one-to-many with B
I want to:
SELECT * FROM A LEFT JOIN B ON A.id = B.a_id ???
But I want to return exactly one row for each entry in A which has the B with the newest t field (or null for Bs fields if it has no B entry).
That is rather than returning all A-B pairs, I want to only select the newest one with respect to A (or A-null if no B entry).
Is there some way to express this in SQL? (I'm using MySQL 5.5)
LEFT JOIN is only concerned with ensuring every row in A is returned, even if there is no corresponding joined row in B.
The need for just one row needs another condition. MySQL is limitted in its options, but one could be:
SELECT
*
FROM
A
LEFT JOIN
B
ON B.id = A.id
AND B.t = (SELECT MAX(lookup.t) FROM B AS lookup WHERE lookup.id = A.id)
Another could be...
SELECT
*
FROM
A
LEFT JOIN
(
SELECT id, MAX(t) AS t FROM B GROUP BY id
)
AS lookup
ON lookup.id = A.id
LEFT JOIN
B
ON B.id = lookup.id
AND B.t = lookup.t
You could do the following:
SELECT A.*, B.*
FROM
A
LEFT JOIN
(SELECT B.a_id, MAX(t) as t FROM B GROUP BY B.a_id) BMax
ON A.id = BMax.a_id
JOIN B
ON B.a_id = BMax.a_id AND B.t = BMax.t
you first need to get the newest t from tableB in a subquery, then join it with tableA and tableB.
SELECT a.*, c.*
FROM tableA a
LEFT JOIN
(
SELECT a_ID, max(t) maxT
FROM tableB
GROUP BY a_ID
) b on a.a_id = b.a_ID
LEFT JOIN tableB c
ON b.a_ID = c.a_ID AND
b.maxT = c.t
try this:
SELECT *
FROM tableA A LEFT JOIN
(select a_id ,max(t) as max_t
from tableB
group by a_id )b
on A.id = b.a_id
and A.t=b.max_t

Left Joins not Working with Subquery

I am trying to write this SQL:
SELECT
a.a_id as aid,
b.b_id as bid ,
c.title
FROM b ,
( SELECT
a.a_id
FROM a
WHERE a.type = '2'
) AS a
LEFT JOIN c ON b.b_id = c.c_id
If I don't put a reference to the LEFT JOIN or the select c, then it works. If I do put the left join, then I get an error that the b.b_id is an unknown column. Why can't I use a left join here or more specifically, why is any column in table b unknown? The first part of the statement is a normal select from table b, so why can't it find those columns?
When do you use subqueries versus inner joins? In this example:
Table a contains fixed length flags (a bunch of integers) with information about topics
Table c contains things like topic title, etc.
Table b contains the category information.
What I am trying to accomplish is to pull all categories of a certain type (table a), and also pull all topic titles (table c) where the category id is the same as what it is defined for the topic id (table b).
If you interchange table "a" with "b" the sql compiles (but does this give the results you seek?):
SELECT
a.a_id as aid,
b.b_id as bid,
c.title
FROM
( SELECT
a.a_id
FROM a
WHERE a.type = '2'
) AS a, b
LEFT JOIN c ON b.b_id = c.c_id
Try this
SELECT
a.a_id as aid,
b.b_id as bid ,
c.title
FROM b INNER JOIN
( SELECT
a.a_id
FROM a
WHERE a.type = '2'
) AS a
LEFT JOIN c ON b.b_id = c.c_id