I have the two tables below:
I want to list all items that have been selected for event 2099 but NOT for event 2201. How would I do this?
I have this:
SELECT ITEMNO, UNIT_PRICE, EST_SERVINGS
FROM MENUITEM
WHERE ITEMNO IN (SELECT ITEMNO FROM SELECTEDITEM WHERE EVENTID = 2099);
but this only returns the itemno's with event 2099. The answer should just be 520.
I am a fan of using aggregation with a having
clause for this type of query.
SELECT mi.ITEMNO, mi.UNIT_PRICE, mi.EST_SERVINGS
FROM MENUITEM mi JOIN
SELECTEDITEM si
ON mi.ITEMNO = si.ITEMNO
GROUP BY mi.ITEMNO, mi.UNIT_PRICE, mi.EST_SERVINGS
HAVING SUM(CASE WHEN EVENTID = 2099 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN EVENTID = 2201 THEN 1 ELSE 0 END) = 0;
Each condition in the having
clause is counting the number of times that a particular item is used for an event. The > 0
means the item is used at least once. The = 0
means the item does not appear. So the first says that the item was used for event 2099 and the second that the item was not used for 2202.
I like this method of expressing these "set-within-sets" queries because it is very flexible. If you want to say that event 2101 should be included, just add another clause:
HAVING SUM(CASE WHEN EVENTID = 2099 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN EVENTID = 2101 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN EVENTID = 2201 THEN 1 ELSE 0 END) = 0;
Try this:
SELECT ITEMNO, UNIT_PRICE, EST_SERVINGS
FROM MENUITEM MI
WHERE
EXISTS
(SELECT 'ON2099'
FROM SELECTEDITEM SI
WHERE SI.ITEMNO = MI.ITEMNO AND SI.EVENTID = 2099)
AND NOT EXISTS
(SELECT 'ON2201'
FROM SELECTEDITEM SI
WHERE SI.ITEMNO = MI.ITEMNO AND SI.EVENTID = 2201)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.