MYSQL - How do I create a single query to accomplish this - mysql

I have a fairly complex situation where I'd like to see if there is a single query I can use to get the data.
In the following pseudo code, assume the "*" in each select clause has the appropriate columns selected and that table3 and table4 have similar enough columns that I can handle the diffs with padding/fake columns.
select * from table1 where ActiveFlag=1
for each row returned (as A)
//check if member has a record in membership table
select * from table2 where MembershipId=A.MembershipId
if (row exists)
select * from table3 where MemberId=A.MemberId
else
select * from table4 where MembershipId=A.MembershipId
end of for loop

This assumne each row in TableA can have 0-1 membership, otherwise we need to filter duplicates first.
SELECT CASE WHEN M.MembershipId IS NULL
THEN T4.field1
ELSE T3.field1
END as field1,
....
CASE WHEN M.MembershipId IS NULL
THEN T4.fieldN
ELSE T3.fieldN
END as fieldN
FROM TableA A
LEFT JOIN Membership M
ON A.MembershipId = M.MembershipId
CROSS JOIN table3 T3
CROSS JOIN table4 T4
WHERE A.MemberId = T3.MemberId
OR A.MembershipId = T4.MembershipId
If you have duplicate Membership replace the first two JOIN with something like this.
FROM (
SELECT DISTINCT TableA.*, M.MembershipId
FROM TableA A
LEFT JOIN Membership M
ON A.MembershipId = M.MembershipId
) A
CROSS JOIN ..

Related

MS Access: find rows with different fields in two tables

In MS Access:
I am trying to compare two tables with:
- TABLE1.docnumb1 = TABLE2.docnumb2
- looking for: TABLE1.sum <> TABLE2.sum2
But query retrieves an error: syntax error in from clause (or when creating left join I get an error that JOIN isn't supported):
SELECT docnumb1, sum
FROM Table1
JOIN Table2 ON docnumb1 = docnumb2;
How do I query the rows with different values?
looking to your sample (image)
you could compare the subquery for sum
select t1.rownumb, t1.sum1 -t2.sum2
from (
SELECT rownumb, sum(value) sum1
FROM Table1
group by rownumb
) t1
INNER JOIN
(
SELECT rownumb, sum(value) sum2
FROM Table2
group by rownumb
) t2 ON t1.rownumb = t2.rownumb and (t1.sum1 -t2.sum2 ) <> 0
use left join
SELECT docnumb1, sum
FROM Table1 a
left JOIN Table2 b ON a.docnumb1 = b.docnumb2 and a.value=b.value
where b.docnumb2 is null

Select join statement is not working

I'm trying to make an output array from next statement:
I have 2 tables. In each table there is "material_code" which plays the main role. I want to select material_code from table1 where it'is equal to material_code from table2 and join them where status (from table2) is equal to 0.
This is what I've got so far.
SELECT material_code FROM table1
LEFT JOIN table2 ON material_code WHERE status IS 0
Solution:
SELECT material_code FROM table1
LEFT JOIN table2 ON table1.material_code = table2.material_code WHERE status = 0
Thank everyone.
You should try this one:
SELECT
material_code
FROM table1
LEFT JOIN table2
ON table1.material_code = table2.material_code
WHERE status = 0
Sounds like you want an INNER JOIN
SELECT material_code FROM table1
INNER JOIN table2 USING (material_code) WHERE status = 0
If you use LEFT JOIN, you will get records that only exist in table1 and not in table2. You also want to use USING not ON if the column name is the same in both tables (at least in MySQL).
WHERE status IS 0
should be
WHERE status = 0
Only when for null it have to be IS NULL.
And you also missed the join condition (ON table1.material_code = table2.material_code)
If you have a field 'status' in bot table, you can use an explicit table name before the field name to add a condition only on 'status' of table1 like :
WHERE table2.status = 0
Try this SQL code. INNER JOIN is better in your case.
SELECT tb1.material_code
FROM table1 as tb1
INNER JOIN table2 as tb2 ON tb1.material_code=tb2.material_code
WHERE tb2.status = 0

3 tables and 2 left joins

Query 1:
SELECT sum(total_revenue_usd)
FROM table1 c
WHERE c.irt1_search_campaign_id IN (
SELECT assign_id
FROM table2 ga
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
)
Query 2:
SELECT sum(total_revenue_usd)
FROM table1 c
LEFT JOIN table2 ga
ON c.irt1_search_campaign_id = ga.assign_id
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
Query 1 gives me the correct result where as I need it in the second style without using 'in'. However Query 2 doesn't give the same result.
How can I change the first query without using 'in' ?
The reason being is that the small query is part of a much larger query, there are other conditions that won't work with 'in'
You could try something along the lines of
SELECT sum(total_revenue_usd)
FROM table1 c
JOIN
(
SELECT DISTINCT ga.assign_id
FROM table2 ga
JOIN table3 d
ON d.campaign_id = ga.assign_id
) x
ON c.irt1_search_campaign_id = x.assign_id
The queries do very different things:
The first query sums the total_revenue_usd from table1 where irt1_search_campaign_id exists in table2 as assign_id. (The outer join to table3 is absolutely unnecessary, by the way, because it doesn't change wether a table2.assign_id exists or not.) As you look for existence in table2, you can of course replace IN with EXISTS.
The second query gets you combinations of table1, table2 and table3. So, in case there are two records in table2 for an entry in table1 and three records in table3 for each of the two table2 records, you will get six records for the one table1 record. Thus you sum its total_revenue_usd sixfold. This is not what you want. Don't join table1 with the other tables.
EDIT: Here is the query using an exists clause. As mentioned, outer joining table3 doesn't alter the results.
Select sum(total_revenue_usd)
from table1 c
where exists
(
select *
from table2 ga
-- left join table3 d on d.campaign_id = ga.assign_id
where ga.assign_id = c.irt1_search_campaign_id
);

Subquery That Shows Records Only Where the JOIN Doesn't Work

I created a relatively simple query in MySQL to give me a JOIN on three tables based on where first names and last names matched. From there, I wanted to write another query that would then only show me the records that didn't get matched from the JOIN -- but I couldn't quite figure out how to do it. I'm assuming that it has to do with using a subquery involving something like NOT IN and my original query, but I couldn't get it to give me the results I wanted.
This is the work-around I tried to come up with that partially functioned properly:
SELECT *,
if(t2.first=t1.first AND t2.last=t1.last, "Match", "No Match") AS "t2 Match",
if(t3.first=t1.first AND t3.last=t1.last, "Match", "No Match") AS "t3 Match"
FROM t1
LEFT JOIN t2 ON t2.first=t1.first AND t2.last=t1.last
LEFT JOIN t3 ON t3.first=t1.first AND t3.last=t1.last
WHERE if(t2.first=t1.first AND t2.last=t1.last, "Match", "No Match")="No Match"
OR if(t3.first=t1.first AND t3.last=t1.last, "Match", "No Match")="No Match";
I feel like this is something that's fairly simple and straight-forward, but I'm not getting the correct results. Can anybody help?
Thanks!
No match means that the t2 (or t3) columns are populated with Nulls in the results. So you can use IS NULL checks:
SELECT t1.*
FROM t1
LEFT JOIN t2 ON t2.first = t1.first AND t2.last = t1.last
LEFT JOIN t3 ON t3.first = t1.first AND t3.last = t1.last
WHERE t2.first IS NULL
OR t3.first IS NULL ;
And you were right, you can also write the queries using NOT IN (warning: only if the joining columns are not nullable. Otherwise you may have unexpected results):
SELECT t1.*
FROM t1
WHERE (first, last) NOT IN
( SELECT first, last FROM t2 )
OR (first, last) NOT IN
( SELECT first, last FROM t3 )
;
or using NOT EXISTS:
SELECT t1.*
FROM t1
WHERE NOT EXISTS
( SELECT 1
FROM t2
WHERE t1.first = t2.first
AND t1.last = t2.last
)
OR NOT EXISTS
( SELECT 1
FROM t3
WHERE t1.first = t3.first
AND t1.last = t3.last
) ;

How do I merge two tables in SQL?

I've got two tables:
Table 1 = idhash - username - usermail
Table 2 = idhash - views - fistseen - lastseen
Now I want to merge these tables to a new table:
Table 3 = idhash - username - usermail - firstseen - lastseen
*notice that I want to drop the views column.
I've tried with solutions that I found on google, but so far they do not seem to work.
Not all the idhash columns from table 2 have a corresponding idhash in table 1. Stiil store those 'mismatched' rows with empty username and usermail
This query will give you the results:
SELECT A.*, B.firstseen, B.lastseen
FROM [Table 1] A
LEFT JOIN [Table 2] B
ON A.idhash = B.idhash
And to insert and update the results on your [Table 3]:
INSERT INTO [Table 3](idhash, username, usermail, firstseen, lastseen)
SELECT A.*, B.firstseen, B.lastseen
FROM [Table 1] A
LEFT JOIN [Table 2] B
ON A.idhash = B.idhash
LEFT JOIN [Table 3] C
ON A.idhash = C.idhash
WHERE C.idhash IS NULL
-- For SQL Server
UPDATE T3
SET firstseen = T1.firstseen,
lastseen = T1.lastseen
FROM [Table 3] T3
INNER JOIN (SELECT A.*, B.firstseen, B.lastseen
FROM [Table 1] A
LEFT JOIN [Table 2] B
ON A.idhash = B.idhash) T1
WHERE T3.firstseen != T1.firstseen OR T3.lastseen != T1.lastseen
Here's a solution for MySQL:
CREATE TABLE table3
// First get all the rows from table2, paired with matching rows from table1
(SELECT a.idhash, b.username, b.usermail, a.firstseen, a.lastseen
FROM table2 a
LEFT JOIN table1 b
ON b.idhash = a.idhash)
// Now get the remaining rows from table1 that don't have matches
UNION ALL
(SELECT null, a.username, a.usermail, null, null
FROM table1 a
LEFT JOIN table2 b
ON b.idhash = a.idhash
WHERE b.idhash IS NULL)
If you don't want the rows from table1 that don't have corresponding rows in table2, then delete the second query in the UNION clause.
You could just brute force it with your choice of programming language. Just build a new table, query both tables, join rows programmatically however they need to be joined, insert into new table.
insert into table3
select t1.idhash, t1.username, t1.usermail, t2.firstseen,t2.lastseen
from table1 t1 left join table2 t2 on t1.idhas=t2.idhas
This should be a good start. You need to tell us what to do with your mis-matched records before we can give anything more specific.
Select
table1.idhash
,username
,usermail
,firstseen
,lastseen
From table1
left join table2
on table1.idhash = table2.idhash
Create your new table with the field types in your create statement
http://www.w3schools.com/sql/sql_create_table.asp
Then do an insert Into Table3 <yourtable> select a.f1,b.f2,c.f3 from Table1 a, Table 2 b on a.id = b.id
This is pretty close to brute force.
select coalesce(t1.idhash, t2.idhash) as idhash
, username
, usermail
, firstseen
, lastseen
into table3
from table1 t1
cross join table2 t2
try this:
INSERT INTO table3 (idhash, username, usermail, firstseen, lastseen)
SELECT a.idhash, a.username, a.usermail,
b.firstseen, b.lastseen
FROM table1 a LEFT JOIN table2 b
ON a.idhash = b.idhash
I would do this:
CREATE TABLE table3
AS
SELECT idhash, username, usermail, firstseen, lastseen
FROM Table1
NATURAL FULL OUTER JOIN Table2