MYSQL query to match multiple values from two tables - mysql

I'm having trouble fixing a MYSQL query that will find "matches" between 2 relational tables. For example, if the TABLEA ID being passed in was 2, then I want to return all IDs from TABLEB where both TABLEA VALUES (b and c) exist for a single TABLEB ID. Hope that made sense! In this instance it wouldn't return anything. However, when passing in ID 3 it would return 13 as d and e exist within ID 13 rows in TABLEB. Any help massively appreciated!
TABLEA
ID | VALUE
1 | a
2 | b
2 | c
3 | d
3 | e
TABLEB
ID | VALUE
10 | a
12 | b
12 | z
13 | d
13 | e
13 | f

You can try this query.
UPDATE:
In MySQL :
SELECT tab_b.ID
FROM TABLEB tab_b
WHERE tab_b.VALUE IN (SELECT TABLEA.VALUE
FROM TABLEA
WHERE TABLEA.ID = 3)
GROUP BY tab_b.ID
HAVING COUNT(DISTINCT tab_b.VALUE) = (SELECT COUNT(TABLEA.VALUE)
FROM TABLEA
WHERE TABLEA.ID = 3)
Check this Fiddle in MySQL: ->http://sqlfiddle.com/#!2/b1aba/10
Fiddle in SQL Server: -> http://sqlfiddle.com/#!3/b0d63/3
(You'll have to change the values from 2 to 3 to see the desired result)
Hope this helps!!!

select b.id2
from tableA a
left join tableB b
on a.value = b.value2
where a.id = 2
and id2 is not null
hope this answers it for you
here is the fiddle
fiddle
http://sqlfiddle.com/#!3/7e4b1/5

Related

mysql query select from one table such that its column's values are not present in the same column's values in another table

I have two mysql tables: A, and B.
A has columns id, alpha, blabla, moreblabla, with primary key id.
B has columns id, alpha, beta, somemoreblabla, with primary key (id, alpha)
I need to select all those A.id's, for which its A.alpha is not present in any of the B.alpha's respective to every B.id = A.id
How do I do it?
Your question is not entirely clear. Do you want all A.alpha's that are not in any B.alpha? In that case a simple query like this is enough:
Select A.id from A where A.alpha NOT IN (Select B.alpha from B);
If you want to select all ID's from A that have a counterpart (an equal ID) in B but where the alpha between A and B are different it is a bit more work:
SELECT A.id FROM A
INNER JOIN B on A.id = B.id
WHERE A.alpha != B.alpha
Consider the following structure:
CREATE TABLE `A` (
`id` int(11) NOT NULL,
`alpha` varchar(255) NOT NULL
);
CREATE TABLE `B` (
`id` int(11) NOT NULL,
`alpha` varchar(255) NOT NULL
);
With inserts:
insert into A set id = 1, alpha = 'a';
insert into A set id = 2, alpha = 'b';
insert into B set id = 1, alpha = 'a';
insert into B set id = 2, alpha = 'a';
If you run the query with the join your result will be:
+----+
| id |
+----+
| 2 |
+----+
This is since ID 2 in A has a different alpha than ID 2 in B.
EDIT:
It just occurred to me that you might even mean that every A.id can occur in B multiple times. If that is what can happen you need a different approach again. Lets assume the same insert as before with an addition:
insert into A set id = 1, alpha = 'a';
insert into A set id = 2, alpha = 'b';
insert into B set id = 1, alpha = 'a';
insert into B set id = 2, alpha = 'a';
insert into B set id = 2, alpha = 'b'; <- important since there is now a 2nd 2 in B that should ensure that the record with ID 2 from A should not be returned.
insert into A set id = 3, alpha = 'c';
insert into B set id = 3, alpha = 'x'; <-- only ID 3 should now be returned due to the situation above
Our tables now look like so:
A
+----+-------+
| id | alpha |
+----+-------+
| 1 | a |
| 2 | b |
| 3 | c |
+----+-------+
B
+----+-------+
| id | alpha |
+----+-------+
| 1 | a |
| 2 | a |
| 2 | b |
| 3 | x |
+----+-------+
If this is your case the following query will do the trick:
select A.id
FROM A where A.alpha NOT IN (
select B.alpha FROM B where B.id = A.id
);
SELECT A.id
FROM
A
LEFT OUTER JOIN B ON A.id = B.id AND B.alpha = A.alpha
where B.alpha IS NULL
Here is SQL Fiddle
This will be the fastest query,better than The marked Answer in terms of query optimization.
EXPLAIN SELECT A.id
FROM
A
LEFT OUTER JOIN B ON A.id = B.id AND B.alpha = A.alpha
where B.alpha IS NULL
Here is the output :
EXPLAIN select A.id
FROM A where A.alpha NOT IN (
select B.alpha FROM B where B.id = A.id
)
Here is the EXPLAIN of Marked answer.
You can see the DIFFERENCE.
SIMPLE VS PRIMARY
SIMPLE VS DEPENDENT SUBQUERY
Hope this helps.
Use MySQL NOT IN
Try this query :-
select id from a where a.id NOT IN (select id from b)
Select A.id from table_A where A.alpha NOT IN (Select B.alpha from table_B);
The Sub-query will return a table with all the records of B.alpha from table_B.
And say it returns 1 to 5 records as result.
And say your table table_A has 1 to 10 records in A.alpha
Now your parent query will check for records in table table_A for field A.alpha which do not belongs to B.alpha (using NOT IN)
Hence the expected result is 6 to 10 as result.

Sql JOIN request issue

I have got 2 tables.
A :
ida title
1 aaa
2 bbb
3 ccc
and
B :
idb ida date count
1 1 2014-09-15 14:22:37 15
2 1 2014-09-15 15:52:07 34
3 1 2014-09-15 14:25:38 16
I would like to get all the A table rows, the most recent date and the count corresponding in B even if none of them exist in B table.
I expect this result on this example.
A.ida A.title B.date B.count
1 aaa 2014-09-15 15:52:07 34
2 bbb null null
3 ccc null null
Any help would be apreciated :)
Edit : my initial and false request was :
SELECT e.ida, MAX(n.date_add) as date_notification, n.count FROM ida e LEFT JOIN idb n ON e.ida = n.ida group by e.ida
Don't joining it to this initial Stack was akward.
Here is the query you're looking for:
SELECT A.ida
,A.title
,B.date
,B.count
FROM tableA A
LEFT OUTER JOIN (SELECT B.ida
,MAX(B.date) AS [max_date]
FROM tableB B
GROUP BY B.ida) T ON T.ida = A.ida
LEFT OUTER JOIN tableB B ON B.ida = T.ida
AND B.date = T.max_date
ORDER BY A.ida
The first jointure is used to get only the last date for each ida and the second jointure is used to get the corresponding information from tableB.
Hope this will help you.

MySQL join 2 tables and unite a column

I have two tables:
Table A
ID | DATE | VALUE | KEY|
1 30.8.14 100 11
2 25.8.14 500 11
2 20.8.14 250 11
Table B
ID | DATE | VALUE | KEY|
1 30.8.14 AB 11
2 25.8.14 CD 11
3 10.8.14 EF 11
These two tables should be merged, key is used to define which entries should be merged WHERE KEY = '11'
IF there is a date in TABLE A that is also in TABLE B, it becomes on entry with both values
IF there is no date in TABLE A that is also in TABLE B, the value for B becomes (null)
And in the End, there should be only 1 date field.
Columns should also be be a unique name..
I created this example table, how my output should look like
joinedDate | aValue | bValue
30.8.14 100 AB
25.8.14 500 CD
20.8.14 250 (null)
10.8.14 (null) EF
Im using MySQL version 5.5 on Maria DB
Could someone help me here?
You seem to want full outer join, which MySQL doesn't offer. Here is one method:
select d.date, a.value as avalue, b.value as bvalue
from ((select date from a union
select date from b
)
) d left join
a
on a.date = d.date left join
b
on b.date = d.date;
select a.date, a.value as avalue, b.value as bvalue
from tablea a
left join tableb b
on a.date = b.date
union all
select b.date, null, b.value
from tableb b
left join tablea a
on a.date = b.date
where a.date is null
Fiddle:
http://sqlfiddle.com/#!2/09ab9e8/4/0

SQL Server 2008 : Updating a column based on other tables

TableA (id int, match char(15), multiple char(10))
int match multiple
1 100
2 101
3 102
4 103
TableB (match char(15), match2 char(10))
match match2
100 ABC
100 NBG
101 NYF
102 NHW
102 UYQ
103 WOT
Now, I want to populate TableA.multiple = "YES" if in TableB for corresponding match, there exists more than one match2.
Expected result.
int match multiple
1 100 YES
2 101 NULL
3 102 YES
4 103 NULL
Thanks in advance !
My FAILED try:
Update A
SET multiple = 'YES'
From tableA A
Inner join tableB B ON A.match = B.match
WHERE (Select count(distinct(B.match2)) from TableB) > 2
Start with an extra-verbose version, just for its clarity:
UPDATE TableA
SET multiple = 'YES'
WHERE match in (
-- isolate the multiples
SELECT match from (
-- count the matches
SELECT count(*) as c, match from TableB
GROUP BY match ) x
WHERE c > 1
)
With the HAVING clause, you can change this...
SELECT match from (
SELECT count(*) as c, match from TableB
GROUP BY match ) x
WHERE c > 1
...to this:
SELECT match from TableB
GROUP BY match
HAVING count(*) > 1
So now we have:
UPDATE TableA
SET multiple = 'YES'
WHERE match in (
SELECT match from TableB
GROUP BY match
HAVING count(*) > 1
)
I'm sure it can be made more compact, but I personally get confused by UPDATE statements containing non-obvious JOIN clauses, especially in the middle of the night when I get the call that "the database isn't working!"
Don't Make Me Think applies to coding, too.
UPDATE tableA
SET multiple = 'YES'
FROM TableA AS a
JOIN (SELECT match FROM tableB GROUP BY match HAVING COUNT(*) > 1) AS b ON a.match = b.match
UPDATE TableA a
SET multiple='YES'
FROM Tablea a,(SELECT match FROM Tableb GROUP BY match HAVING COUNT(*)>1)b
WHERE a.match=b.match

mysql two table query problem

a table
a_id a_value
1 text1
2 test2
b table
b_id b_num a_id
1 5 1
2 7 1
3 2 1
4 7 2
5 56 2
Results base a table (edited)
a_id:1 a_value:text1 total:3 records
a_id:2 a_value:text2 total:2 records
How can get this format in sql?
query a table and add a field(total) count b.a_id = a.a_id in table b
thank you..
You can try:
SELECT a.a_id AS id, a.a_value AS value, (SELECT count(b.b_id) AS count FROM b WHERE (b.a_id = a.a_id)) AS total FROM a GROUP BY a.a_id
Then the result for your example using the data from tables a and b:
**id value total**
1 text1 3
2 text2 2
I imagine you have an error in your b table, so I will assume what you call b_id is actually a_id, or your results would be wrong
Anyway you could use:
SELECT COUNT(b.a_id) AS total FROM b GROUP BY (SELECT a.a_id FROM a)
ORDER BY b.a_id
The updated query based on changes to the question
SELECT a_id, a_value, x.total
FROM a
INNER JOIN
(SELECT b.a_id, COUNT(1) AS total
FROM b
GROUP BY (b.a_id)) X
ON a.a_id = x.a_id
ORDER BY a.a_id