Find not common users in sql - mysql

I have 5 tables. I want to get specific users in table 1 that are not in table2, table3, table4 and table5. Can someone please help me :)
table1(userid,discount)
table2(userid,discount)
table3(userid,discount)
table4(userid,discount)
table5(userid,discount)

The following query:
SELECT userid
FROM table1 AS t1
WHERE NOT EXISTS (
SELECT 1
FROM (
SELECT userid
FROM table2
UNION
SELECT userid
FROM table3
UNION
SELECT userid
FROM table4
UNION
SELECT userid
FROM table5) AS t2
WHERE t1.userid = t2.userid)
returns all users of table1 that don't exist in any of the other tables.
Demo here
If you also want, say, all users of table2 that don't exist in any of the other tables, then you can modify the above query so as to return users from table2 and perform a UNION between these two queries:
SELECT userid
FROM table1 AS t1
WHERE NOT EXISTS (
SELECT 1
FROM (
SELECT userid
FROM table2
UNION
SELECT userid
FROM table3
UNION
SELECT userid
FROM table4
UNION
SELECT userid
FROM table5) AS t2
WHERE t1.userid = t2.userid)
UNION ALL
SELECT userid
FROM table2 AS t1
WHERE NOT EXISTS (
SELECT 1
FROM (
SELECT userid
FROM table1
UNION
SELECT userid
FROM table3
UNION
SELECT userid
FROM table4
UNION
SELECT userid
FROM table5) AS t2
WHERE t1.userid = t2.userid)
Demo here
The above can easily be extended so as to incorporate users from all tables. But, I have to admit, it becomes quite verbose !

Related

Can a table get other table column data

I need to create a select statement where the statement need to retrieve data from other table column data
eg.
Table1 Table2
id id2
age age2
Select id, age from table 1 where id= id2
Is that possible.
You can use INNER JOIN
SELECT
T1.id,
T1.age
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.id = T2.id2
DEMO using INNER JOIN
You can use EXISTS
SELECT
T1.id,
T1.age
FROM Table1 AS T1
WHERE EXISTS(
SELECT 1
FROM Table2 AS T2
WHERE T2.id2 = T1.id
);
You can use IN
SELECT
T1.id,
T1.age
FROM Table1 AS T1
WHERE T1.id IN (SELECT T2.id2 FROM Table2 AS T2)
Note:
In the working demo the output consists of two rows. There are two entries in tabel1 and three entries in table2. But there are only two matching entries found between these two tables. That's why output consists of only two rows.
Yes you can. It is called a JOIN and there are several types of JOINs. I suggest you read up on them on SQL JOINs.
SELECT id ,age
FROM TABLE 1
WHERE id IN (SELECT id2 FROM TABLE2);
OR
SELECT id ,age
FROM TABLE1 , TABLE2
WHERE id = id2 ;
OR
SELECT id ,age
FROM TABLE 1 , (SELECT id2 FROM TABLE2) TBL2
WHERE id = TBL2.id2 ;

sql to extract same columns from 3 different tables

Hi i have 3 tables i want to extract same columns from 3 tables is this better way to write Select query.
select * from
(
select col1,
select id1 from testid1 where name=pnrtable1.name,
col3 from table1
union all
select coltab1,
select newid2 from testid2 where name=pnrtable2.name,
coltab3 from table2
union all
select namecol1,
select id3 from testid3 where name=pnrtable3.name,
namecol3 from table3
)
Not sure but I think you are after something like this....
select * from
(
select t1.col1, t2.id1 , t1.col3 from table1 t1
INNER JOIN testid1 t2 ON t1.name = t2.name
union all
select t1.coltab1, t2.newid2, t1.coltab3 from testid2 t1
INNER JOIN table2 t2 ON t1.name=t2.name
union all
select t1.namecol1, t2.id3, t1.namecol3 from testid3 t1
INNER JOIN table3 t2 ON t1.name=t2.name
) A

Joining three tables such that extra matches are discarded?

How can I write a query to give the results of three tables such that there's only one result per "line"?
The tables are:
T1 (ID, name, IP)
T2 (ID, date_joined)
T3 (ID, address, date_modified)
The relations are:
T1-T2 1:1, T1-T3 1:M - there can be many address rows per ID in T3.
What I want is a listing of all users with the fields above, but IF they have an address, I only want to record ONE (bonus would be if it is the latest one based on T3.date_modified).
So I should end up with exactly the number of records in T1 (happens to be equal to T2 in this case) and no more.
I tried:
select t.ID, t.name, t.IP, tt.ID, tt.date_joined, ttt.ID, ttt.address
from T1 t JOIN T2 tt ON (t.ID = tt.ID) JOIN T3 ttt ON (t.ID = ttt.ID)
And every sensible combination of LEFT, RIGHT, INNER, etc joins I could think of! I keep getting multiple duplicate because of T3
This query should work:
select
t1.ID, t1.name, t1.IP, t2.date_joined, t3x.address
from t1
join t2 on t1.ID = t2.id
left join (
select t3.*
from t3
join (
select id, max(date_modified) max_date
from t3
group by id
) max_t3 on t3.id = max_t3.id and t3.date_modified = max_t3.max_date
) t3x on t1.ID = t3x.id
First you do the normal join between t1 and t2 and then you left join with a derived table (t3x) that is the set of t3 rows having the latest date.
So T2 is actually not relevant here. You just need a way to join from T1 to T3 in a way that gets you at most one T3 row per T1 row.
One way of doing this would be:
select
T1.*,
(select address from T3 where T3.ID=T1.ID order by date_modified desc limit 1)
from T1;
This won't likely be very efficient, being a correlated subquery, but you may not care depending on the size of your dataset.
It's also only good for getting one column from T3, so if you had Address, City, and State, you'd have to figure out something else.
You can use sub query with Top 1 so that u get only one result from T3
here is a sample sql
select * into #T1 from(
select 1 ID
union select 2
union select 3) A
select * into #T2 from(
select 1 ID
union select 2
union select 3) A
select * into #T3 from(
select 1 ID, 'ABC' Address, getDate() dateModified
union select 1, 'DEF', getDate()
union select 3, 'GHI', getDate()) A
select *, (select top 1 Address from #T3 T3 where T3.ID= T1.ID order by datemodified desc) from #T1 T1
inner join #T2 T2 on T1.ID = T2.ID
Bonus :- you can also add order by dateModified desc to get the latest address

use a mysql query result to do another query

I have 2 table table1 contains an userid and a postid. Table2 contains a userid and a username. I want to return all the userids with a certain postid and then use those userids to query table2 and get the usernames.
Is there a way to go about this? I have tried join statement and it doesn't seem to work
Use the IN function:
select username, userid from `table2` where userid in (select userid from `table` where postid = <condition>)
SELECT A.postid, A.userid, B.username FROM
tableA AS A JOIN tableB AS B ON A.userid=B.userid
select post id, user id from tableA username from tableB. Join these 2 different table columns when tableA's userid is equal to tableB's userid.
select t1.postid, t1.userid, t2.username
from table1 t2
left join table1 t2 on t1.userid = t2.userid
where t1.postid = <your postid>
Join the tables on the common columns
select t1.postid, t1.userid, t2.username
from table1 t1
join table2 t2 on t1.userid = t2.userid
where t1.postid = 2

MySQL Union for two tables, then merge in a third table where matched?

I have three MySQL tables that I'm trying to query into a single result. As close as I've gotten this, I think it's possible, but I've hit a wall in getting the last part working.
Basically I have two tables (table_one and table_two) which I'm trying to UNION DISTINCT, which works perfectly. It's when I try to bring in the third table that it all blows up and decides to return nothing. I'm sure it's user error :)
This code may not have everything in the right place for how I'm trying to do it, so maybe I just need a little nudge in the right direction.
SELECT
part_code,
name
FROM
table_three
WHERE
table_three.part_code = (
SELECT
part_code
FROM
table_one
UNION DISTINCT
SELECT
part_code
FROM
table_two
)
ORDER BY
name ASC
I appreciate any direction someone can offer.
WHERE
table_three.part_code IN(
^^
Edit
Here are some alternatives that satisfies: Gief all rows in Table 3 such that the part code exists in either Table 1 or Table 2.
select t3.part_code
,t3.name
from table_three t3
where part_code in(select t1.part_code from table_one t1)
or part_code in(select t2.part_code from table_two t2);
Derived table with union
select t3.part_code
,t3.name
from table_three t3
join (select part_code from table_one
union
select part_code from table_two
) t12
on(t3.part_code = t12.part_code);
Inner join with union
select t3.part_code
,t3.name
from table_three t3
join table_one t1 on(t3.part_code = t1.part_code)
union
select t3.part_code
,t3.name
from table_three t3
join table_two t2 on(t3.part_code = t2.part_code);
Bonus. I have no idea why I did this.
select t3.part_code
,t3.name
from table_three t3
left join (select distinct part_code
from table_one) t1 on(t3.part_code = t1.part_code)
left join (select distinct part_code
from table_two) t2 on(t3.part_code = t2.part_code)
where t3.part_code = t1.part_code
or t3.part_code = t2.part_code;
Let me know how they work out.
Edit 2.
Ok, try the following. It should produce the union of tables T1 and T2. Then for each row, it will pick the name from T3 if such a part code can be found.
If part_code is a key in all tables, you can do a UNION ALL instead.
select T12.part_code
,coalesce(T3.name, T12.name) as name
from (select part_code, name from table_one T1 union
select part_code, name from table_two T2
) T12
left join table_three T3 on(T1.part_code = T3.part_code);
try something like this :)
SELECT
part_code,
name
FROM
table_three
WHERE
table_three.part_code = (
SELECT
part_code
FROM
table_one
UNION DISTINCT (
SELECT
part_code
FROM
table_two
))
ORDER BY
name ASC;