问题
I currently have this SQL query and this output.
SELECT b.HotelNo,g.guestName,b.dateFrom,b.dateToFrom Booking b, Guest g
FROM Booking b, Guest g
WHERE b.guestNo = g.guestNo
GROUP BY b.hotelNo,b.dateFrom,b.dateTo,g.guestName;
I am getting this output: Output
How do I remove all the rows that are not duplicates of first two columns?
Output would be (In words Get all the hotel numbers guest names and dates of stay of all guest only if they have stayed in the same hotel more than once):
1234 John Doe 2017-02-01 00:00:00.000 2017-02-28 00:00:00.000
1234 John Doe 2017-03-16 00:00:00.000 2017-03-21 00:00:00.000
EDIT:
I got what I wanted but I when I add b.dateFrom,b.dateTo into my select statement. I get an error saying: Column 'Booking.dateFrom' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
This is the SQL query that gets this error:
SELECT b.hotelNo,g.guestName,b.dateFrom,b.dateTo
FROM Booking b, Guest g
WHERE b.guestNo = g.guestNo
GROUP BY b.hotelNo,g.guestName
HAVING COUNT(*) > 1;
If I add those two column names in (which I need) I get the error above. How do I add them in without getting an error?
回答1:
If you want only those who have stayed in a hotel more than once, use either a JOIN or an EXISTS clause to check whether the count is greater than two.
Using EXISTS:
SELECT DISTINCT b.hotelNo,g.guestName,b.dateFrom,b.dateTo
FROM Booking AS b
JOIN Guest AS g
ON b.guestNo = g.guestNo
WHERE EXISTS
(
SELECT 1
FROM Booking
WHERE hotelNo = b.hotelNo
AND guestNo = b.guestNo
GROUP BY hotelNo, guestNo
HAVING COUNT(*) > 1
);
Using a JOIN (but same principle):
SELECT DISTINCT b.hotelNo,g.guestName,b.dateFrom,b.dateTo
FROM Booking AS b
JOIN Guest AS g
ON b.guestNo = g.guestNo
JOIN
(
SELECT hotelNo, guestNo
FROM Booking
GROUP BY hotelNo, guestNo
HAVING COUNT(*) > 1
) AS j
ON j.hotelNo = b.hotelNo
AND j.guestNo = b.guestNo;
NOTE: I'm not sure that you need DISTINCT or a GROUP BY on your columns unless you actually have duplicates in your tables (and if you do, you probably should get rid of those duplicates).
回答2:
If you don't mind picking only one of the "dateFrom"s (first or last depending on the order clause) then you can assign a row number to each row, partitioning by the first two columns. Then only pick the first rows of each group (RN=1) which has the same first two column
WITH CTE AS
( SELECT ROW_NUMBER()
OVER ( PARTITION BY b.HotelNo,g.guestName
ORDER BY b.dateFrom) AS RN,
b.HotelNo,g.guestName,b.dateFrom,b.dateTo
FROM Booking b, Guest g
WHERE b.guestNo = g.guestNo
GROUP BY b.hotelNo,b.dateFrom,b.dateTo,g.guestName;
)
SELECT HotelNo,guestName,dateFrom,dateToFrom
WHERE RN=1
You can read more HERE
来源:https://stackoverflow.com/questions/43083226/restricting-uniques-from-showing