Using mySQL to compare 2 tables - mysql

I'm trying to compare 2 mySQL tables to find differences between them. A record may be found in TableA but not in TableB, or vice versa.
My tables are as follows:
TableA
Name A1 A2 B1 B2
------------------------
John 11 12 21 23
John 11 12 21 22
John 33 34 31 33
Mary 41 42 54 55
Mary 71 72 81 82
Mary 41 42 51 52
TableB
Name A1 A2 B1 B2 C D
---------------------------------
John 11 12 21 22 999 999
John 21 23 11 12 999 999
John 31 32 33 34 999 999
Mary 41 42 51 52 999 999
Mary 54 55 41 42 999 999
Columns A1 and A2 is considered a group, and B1 and B2 considered another group. For a record to be considered found in both tables, I need
- TableA(A1,A2) = TableB(A1,A2) AND TableA(B1,B2) = TableB(B1,B2)
OR
- TableA(A1,A2) = TableB(B1,B2) AND TableA(B1,B2) = TableB(A1,A2)
For the 2 tables, above, I would compare all of TableA's John to all of TableB's John, and all of TableA's Mary to all of TableB's Mary.
I should get the output
Name A1 A2 B1 B2 C D
-----------------------------------------------
John 31 32 33 34 999 999 (from TableB)
Mary 41 42 54 55 (from TableA)
Mary 71 72 81 82 (from TableA)
Mary 54 55 41 42 999 999 (from TableB)
I'm new to mySQL, and the above seems so complicated to me that I'm not even sure where to start.
I would really appreciate any help on this.

If I understood you correctly, you need to issue two queries: one for finding records from TableA not existing in TableB, and second one for the opposite situation. Note that in one case it's LEFT JOIN and in the second case it's RIGHT JOIN.
SELECT a.*, '' AS C, '' AS D, '(from TableA)' AS 'table'
FROM TableA AS a
LEFT JOIN TableB AS b
ON ((a.A1 = b.A1 AND a.A2 = b.A2 AND a.B1 = b.B1 AND a.B2 = b.B2)
OR (a.A1 = b.B1 AND a.A2 = b.B2 AND a.B1 = b.A1 AND a.B2 = b.A2))
AND a.Name = b.Name
WHERE b.Name IS NULL
UNION
SELECT b.*, '(from TableB)' AS 'table'
FROM TableA AS a
RIGHT JOIN TableB AS b
ON ((a.A1 = b.A1 AND a.A2 = b.A2 AND a.B1 = b.B1 AND a.B2 = b.B2)
OR (a.A1 = b.B1 AND a.A2 = b.B2 AND a.B1 = b.A1 AND a.B2 = b.A2))
AND a.Name = b.Name
WHERE a.Name IS NULL

Related

How to reference on a different row when you have a joint key in MySQL workbench?

my code in MySQL workbench
SELECT
id,
user_id,
parent_id,
approved_time,
#new_approved_t:=IF(new_product_type != 'B', approved_time, #new_approved_t))AS new_approved_time
FROM p
my data frame look like this after I run the code:
id user_id parent_id product_type approved_time New_approved_time
30 11 NA A 8/4/2017 8/4/2017
31 11 30 B 12/1/2017 8/4/2017
54 5 NA A 5/5/2018 5/5/2018
322 5 54 B 7/22/2018 5/5/2018
21 5 NA C 8/1/2018 8/1/2018
13 5 NA C 8/2/2018 8/2/2018
2445 5 NA C 9/25/2018 9/25/2018
111 44 NA A 10/4/2018 10/4/2018
287 44 111 B 10/8/2018 10/4/2018
211 33 NA A 12/5/2018 12/5/2018
277 33 211 B 12/25/2018 12/5/2018
1120 33 NA C 1/1/2019 1/1/2019
1389 33 211 B 1/11/2019 1/1/2019
I would like all my product_type ending in 'B' and it's new_approved_time column to use the corresponding parent_id approved time. The result should look like in below:
id user_id parent_id product_type approved_time New_approved_time
30 11 NA A 8/4/2017 8/4/2017
31 11 30 B 12/1/2017 8/4/2017
54 5 NA A 5/5/2018 5/5/2018
322 5 54 B 7/22/2018 5/5/2018
21 5 NA C 8/1/2018 8/1/2018
13 5 NA C 8/2/2018 8/2/2018
2445 5 NA C 9/25/2018 9/25/2018
111 44 NA A 10/4/2018 10/4/2018
287 44 111 B 10/8/2018 10/4/2018
211 33 NA A 12/5/2018 12/5/2018
277 33 211 B 12/25/2018 12/5/2018
1120 33 NA C 1/1/2019 1/1/2019
1389 33 211 B 1/11/2019 12/5/2018 <-this is where I dont know how to write my code
Thank you!
Found a solution here with another column I didn't include in my example, but basically it's the reverse of parent_id column I listed above which only listed id in product_type A and rest of them is null.
But I got hint from Dan's code on COALESCE() function, thanks Dan.
CASE WHEN c.new_product_type IN ('A', 'B') THEN #new_approved_t:=IF(COALESCE(if((a.is_loc=1 AND b.ploc_RID IS NOT NULL), a.id, null)), a.approved_time, #new_approved_t)
ELSE a.approved_time END AS new_approved_time
Because the parent (pp) has its own value there needs to be a self join like this. Because of the join criteria pp.approved_time will be NULL for non-B products.
SELECT
p.id,
p.user_id,
p.parent_id,
p.approved_time,
COALESCE(pp.approved_time, p.approved_time) AS new_approved_time
FROM p
LEFT JOIN p AS pp ON p.new_product_type = 'B' AND p.parent_id = pp.id

Converting Rows in Datas to Columns for results obtained from multiple joins in Mysql

SELECT DataID.unique_id as unique_id, question.question_id
FROM DataID
RIGHT JOIN bookend
on DataID.user_id = bookend.user_id and DataID.client_id = bookend.client_id
LEFT JOIN question
on bookend.user_id = question.user_id
where type = 'test';
I am getting this value
unique_id question_id answer_id
2333 23 1
2333 24 5
2333 25 10
321 23 2
321 24 6
321 25 7
But i need to display it as
unique_id Q1 A1 Q2 A2 Q3 A3
2333 23 1 24 5 25 10
321 23 2 24 6 25 7
How Could i do this?

Fetch Data from master table based on child table condition in sql server

Need to fetch data from master table based on child table condition.
Master Table:-
ID Name Address
1 abc xyz
2 abs txt
3 aui tre
4 pop top
5 the tre
6 pot tos
7 pog sop
8 pat top
9 bat cric
10 not kot
Child Table:-
chid shootid imagename IDFK
101 234 123ab.jpg 3
102 234 54abcab.jpg 3
103 235 123abc.jpg 3
104 236 12390acb.jpg Null
105 235 12332aab.jpg 8
106 234 123786ab.jpg 4
107 234 54789abcab.jpg 10
108 235 122343abc.jpg 10
109 235 122123acb.jpg 4
110 234 12123aab.jpg 9
111 234 1223ab.jpg Null
112 233 5432abcab.jpg Null
113 235 1239abc.jpg Null
114 236 1238acb.jpg 2
115 236 12356aab.jpg 2
116 236 1235ab.jpg 2
117 236 545abcab.jpg Null
118 237 1233abc.jpg 1
119 237 1223acb.jpg 1
120 237 1123aab.jpg 1
In Child table IDFK is the foreign key and ID in Master table is the primary key of that.
Now i want to show those name from master table that doesn't exist on child table filter on shootid like where childtable.Shootid=234. I tried but not find the desired output.Every time it just return's the same out for different shootid as well.
Please help me and show me the right query for that.
I don't know if I am understand you well or not but I think this is what you want,
Select * from [master] m
where m.ID not in (Select IDFK from detail where shootid=234)
I think this is what you are looking for.
Select distinct m.name from master m LEFT OUTER JOIN child c
ON m.id = c.id and
c.shootid=234
where
c.id is null

Using "OR" versus "AND" Operator for Getting Specific Results

Will do my best to explain my problem here. I ran a query which works good for checking people who have completed either courseIDNum=11 or courseIDNum=12 in districtIDNum=5, but NOT both courseIDNums. Here is the script:
SELECT max(p.FirstName),
max(p.LastName),
max(p.Email),
max(s.CourseIDNum)
FROM People p
INNER JOIN Registration r
on p.PeopleID = r.PeopleIdNum
INNER JOIN Section s
on r.SectionIDNum = s.SectionID
INNER JOIN School sc
on p.SchoolIDNum = sc.SchoolID
WHERE s.CourseIDNum IN (11, 12)
AND sc.DistrictIDNum = 5
AND r.Completed='Y'
group by p.PeopleID
having count(distinct s.CourseIDNum)=1
Now I am tasked to retrieve data for the people in districtIDNum=5 again, but this time to check if they have taken all 3 courses, which 2 out of the 3 courses have the same course name but each of these 2 courses has 2 different courseIDNums. So, I edited the WHERE portion shown below. The results returned are only people who completed 12 and 177, there is no result for 11, 68 and 128. Then, I replaced the OR with the AND operator, and 0 rows is returned. Any help in this is much appreciated!
WHERE s.CourseIDNum IN (11, 12)
OR s.CourseIDNum IN (68, 177)
OR s.CourseIDNum=128
AND sc.DistrictIDNum = 5
AND r.Completed='Y'
group by p.PeopleID
having count(distinct s.CourseIDNum)=3
Here are the tables involved:
peopleID FirstName LastName Email schoolIDNum
1 Esther B b#hotmail.com 33
2 Tommy L l#hotmail.com 55
3 Liz M m#hotmail.com 90
registrationID peopleIDNum sectionIDNum
22 1 40
23 2 41
24 3 132
25 1 78
26 2 52
27 1 63
sectionID courseIDNum
40 11
41 12
52 68
63 128
78 177
132 195
courseID coursename
11 Health (Old)
12 Health (New)
68 PE (Old)
128 Keyboarding
177 PE (New)
195 Computing
schoolID districtIDNum
33 5
55 5
90 12

mysql several column ranking per group

I have table data in this format
studno name level year term subject1 subject2 subject3
212 victor l1 2000 1 45 56 80
213 HOM l1 2000 1 42 56 70
214 ken l1 2000 1 60 70 50
215 ted l1 2000 1 46 36 47
212 victor l1 2000 2 45 36 68
213 Hom l1 2000 2 38 78 49
214 ken l1 2000 2 38 34 62
my desired output is the following
studno name level year term subject1 sub1rank subject2 sub2rank
213 victor l1 2000 1 42 3 56 2
214 HOM l1 2000 1 60 1 70 1
215 TED l1 2000 1 46 2 36 3
212 victor l1 2000 2 45 2 36 1
213 hOM l1 2000 2 38 3 36 1
214 KEN l1 2000 2 38 3 32 3
215 TED l1 2000 2 90 1 30 4
I have managed to get the rank but the problem is how to get the rank per year, level, term and subject. another problem is that if i use nested statement and try to create view in mysql database it throws an error, "View's SELECT contains a subquery in the FROM clause"
You can do this with correlated subqueries in the select clause. If I understand correctly, something like this:
select t.*,
(select COUNT(distinct t1.subject1)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject1 >= t.subject1
) as subj1rank,
(select COUNT(distinct t2.subject2)
from t t2
where t2.level = t.level and t2.year = t.year and t2.term = t.term and
t2.subject2 >= t.subject2
) as subj2rank
from t
The count(*) might be count(distinct subject1) (etc.), depending on how you treat ties.