-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1.4.sql
119 lines (108 loc) · 3.02 KB
/
1.4.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
-- Breeds that were never adopted
-- Try the OUTER JOIN approach (doesn't work...)
SELECT DISTINCT -- AN.Name,
AN.Species,
AN.Breed
FROM Animals AS AN
LEFT OUTER JOIN
Adoptions AS AD
ON AN.Species = AD.Species
AND
AN.Name = AD.Name
WHERE AD.Species IS NULL; /*Species and breeds of animals who were never adopted != Breeds that were never adopted...*/
-- Do we have non breed animals that were adopted?
SELECT *
FROM Animals AS AN
INNER JOIN
Adoptions AS AD
ON AD.Name = AN.Name
AND
AD.Species = AN.Species
WHERE AN.Breed IS NULL;
-- Try the NOT EXISTS approach (doesn't work...)
SELECT DISTINCT Species, Breed
FROM Animals AS AN
WHERE NOT EXISTS (
SELECT NULL
FROM Adoptions AS AD
WHERE AD.Name = AN.Name
AND
AD.Species = AN.Species
);
/* PostgreSQL
-- The NOT IN approach (doesn't work...)
SELECT DISTINCT Species, Breed
FROM Animals AS AN1
WHERE (Species, Breed) NOT IN ( SELECT AN2.Species, AN2.Breed
FROM Animals AS AN2
INNER JOIN
Adoptions AS AD
ON AN2.Species = AD.Species
AND
AN2.Name = AD.Name
);
-- Remove NULLs from subquery (Does it work?)
SELECT DISTINCT Species, Breed
FROM Animals AS AN1
WHERE (Species, Breed) NOT IN ( SELECT AN2.Species, AN2.Breed
FROM Animals AS AN2
INNER JOIN
Adoptions AS AD
ON AN2.Species = AD.Species
AND
AN2.Name = AD.Name
WHERE AN2.Breed IS NOT NULL
);
-- Add Ferris, the non breed ferret that wasn't adopted
INSERT INTO Animals
(Name, Species, Primary_Color, Implant_Chip_ID, Breed, Gender, Birth_Date, Pattern, Admission_Date)
VALUES ('Ferris', 'Ferret', 'White', 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11', NULL, 'F', '20161122', 'Solid', '20171221');
-- Try again
SELECT DISTINCT Species, Breed
FROM Animals AS AN1
WHERE (Species, Breed) NOT IN ( SELECT AN2.Species, AN2.Breed
FROM Animals AS AN2
INNER JOIN
Adoptions AS AD
ON AN2.Species = AD.Species
AND
AN2.Name = AD.Name
WHERE AN2.Breed IS NOT NULL
);
-- Check what happens for NOT IN and an empty set subquery
SELECT 'Works'
WHERE 1 NOT IN (SELECT 1 WHERE FALSE);
-- Cleanup
DELETE FROM Animals WHERE name = 'Ferris' AND Species = 'Ferret';
*/
-- The elegant solution
SELECT Species, Breed
FROM Animals
EXCEPT
SELECT AN.Species, AN.Breed
FROM Animals AS AN
INNER JOIN
Adoptions AS AD
ON AN.Species = AD.Species
AND
AN.Name = AD.Name;
/* PostgreSQL
-- Bonus solution using a different approach.
SELECT DISTINCT Species, Breed
FROM Animals AS AN1
WHERE NOT EXISTS (
SELECT NULL
FROM Animals AS AN2
WHERE EXISTS (
SELECT NULL
FROM Adoptions AS AD
WHERE AD.Name = AN2.Name
AND
AD.Species = AN2.Species
AND
AD.Species = AN1.Species
AND
AN1.Breed IS NOT DISTINCT FROM AN2.Breed
)
);
*/