A piece of SQL that I have written is not behaving as intended. A vital piece of logic involves counting how many guests are VIPs, but the SQL seems to consistently get an incorrect answer.
The following database has 6 guests, 3 of whom are VIPs.
CREATE TABLE `guest` ( `GuestID` int(11) NOT NULL DEFAULT '0', `fullname` varchar(255) DEFAULT NULL, `vip` tinyint(1) DEFAULT '0', ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `guest` -- INSERT INTO `guest` (`GuestID`, `fullname`, `vip`) VALUES (912, 'Sam', 0), (321, 'Sev', 0), (629, 'Joe', 0), (103, 'Tom', 1), (331, 'Cao', 1), (526, 'Conor', 1);
Initially the SQL returned a value saying that there were 5 VIPs, which is incorrect as there are only 3 VIPs. This is quite a complicated database, and in generating a minimum viable example for the sake of this question (with a reproducible error) the script now states that there are only 2 VIPs. Again, this is incorrect.
The SQL in question is
SELECT slotguest.FK_SlotNo, Count(CASE WHEN guest.vip = 1 THEN 1 END) AS guest_count FROM guest INNER JOIN slotguest ON guest.GuestID = slotguest.FK_guest GROUP BY slotguest.FK_SlotNo;
The slotguest structure and content is as follows
CREATE TABLE `slotguest` ( `FK_SlotNo` int(11) NOT NULL, `FK_guest` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `slotguest` -- INSERT INTO `slotguest` (`FK_SlotNo`, `FK_guest`) VALUES (396, 912), (396, 321), (396, 629), (396, 103), (396, 331), (396, 526);
What is causing Count to come up with a consistently incorrect answer?
Advertisement
Answer
As identicated in the comments (check from users @Fábio Amorim, @Rajat), your query seems to work as intended. Since, you set a value with the CASE WHEN
, it might be better to use SUM
.
It might be more visible if you bring the counts for the different VIP categories to find where there might be a leakage of data.
SELECT guest.vip, slotguest.FK_SlotNo, COUNT(*) AS guest_per_category FROM guest INNER JOIN slotguest ON guest.GuestID = slotguest.FK_guest GROUP BY guest.vip,slotguest.FK_SlotNo;