[英]Which SQL clause and function allows you to filter for data about one value? (e.g. purchases made by a single customer or on a single date)
[英]SQL query to select e.g. buyer which made 3 specific buys
我有一張這樣的桌子:
玩具店
+----+------------+-------------------+
| ID | NAME | PURCHASE |
+----+------------+-------------------+
| 1 | Ramesh | Teddy bear |
| 2 | Khilan | Drum |
| 3 | Chaitali | Chess |
| 4 | Hardik | Wooden sword |
|... | ... | ... |
+----+------------+-------------------+
我需要選擇已經完成全部3次購買的所有購買者-泰迪熊,國際象棋和木制劍以及他們的購買
結果應該是這樣的:
+--------+-------------------+
| NAME | PURCHASE |
+--------+-------------------+
| Ramesh | Teddy bear |
| Ramesh | Chess |
| Ramesh | Wooden sword |
| Khilan | Teddy bear |
| Khilan | Chess |
| Khilan | Wooden sword |
+--------+-------------------+
提前致謝
select * from ToyStore ts1 where
exists (select 1 from ToyStore ts2 where
ts1.name=ts2.name and purchase ='Teddy bear')
and
exists (select 1 from ToyStore ts2 where
ts1.name=ts2.name and purchase ='Chess')
and
exists (select 1 from ToyStore ts2 where
ts1.name=ts2.name and purchase ='Wooden sword')
如果要查找每個匹配玩具只有一排且只有這三排的所有名稱,則可以使用以下查詢:(當然,有更聰明的方法,但這很容易理解和更改)
With
-- Data
TOYSTORE AS (
SELECT 1 ID, 'Ramish' NAME, 'Teddy Bear' PURCHASE FROM DUAL UNION ALL
SELECT 2, 'Khilan', 'Drum' FROM DUAL UNION ALL
SELECT 3, 'Chaitali', 'Chess' FROM DUAL UNION ALL
SELECT 4, 'Hardik', 'Wooden sword' FROM DUAL UNION ALL
SELECT 5, 'Hardik', 'Chess' FROM DUAL UNION ALL
SELECT 6, 'Hardik', 'Teddy Bear' FROM DUAL UNION ALL
SELECT 7, 'Chaitali', 'Chess' FROM DUAL UNION ALL
SELECT 8, 'Chaitali', 'Wooden sword' FROM DUAL UNION ALL
SELECT 9, 'Chaitali', 'Teddy Bear' FROM DUAL UNION ALL
SELECT 10, 'Khilan', 'Chess' FROM DUAL UNION ALL
SELECT 11, 'Khilan', 'Wooden sword' FROM DUAL UNION ALL
SELECT 12, 'Khilan', 'Teddy Bear' FROM DUAL
),
-- Matching items
MyMatches AS (
SELECT 'Teddy Bear' PURCHASE FROM DUAL UNION ALL
SELECT 'Chess' FROM DUAL UNION ALL
SELECT 'Wooden sword' FROM DUAL
),
-- all single hits of matching items
MyStrikes AS (
SELECT NAME, PURCHASE, COUNT(*) CNT
FROM TOYSTORE
NATURAL JOIN MyMatches
GROUP BY NAME, PURCHASE
HAVING COUNT(*) = 1
),
-- all names with exactly one item of each kind
My3Strikes AS (
SELECT NAME, SUM(CNT) CNT
FROM MyStrikes
GROUP BY NAME
HAVING SUM(CNT) = 3
),
-- number of all not matching items
MyBlanks AS (
SELECT NAME, COUNT(PURCHASE) CNT --COUNT(PURCHASE) CNT
FROM TOYSTORE
WHERE NOT PURCHASE IN ('Teddy Bear', 'Chess', 'Wooden sword')
GROUP BY NAME
),
-- all names
MyNames AS (
SELECT D.NAME
FROM TOYSTORE D
GROUP BY D.NAME
)
-- the result
SELECT D.NAME
FROM MyNames D
JOIN My3Strikes S ON S.Name = D.Name
LEFT JOIN MyBlanks B ON B.Name = D.Name
WHERE B.CNT IS NULL
;
有些事情對我來說並不完全清楚。 您是否想知道列表中是否有3個項目? 如果是這樣,下一個查詢將有所幫助。
SELECT NAME, COUNT(PURCHASE)
FROM TOYSTORE
GROUP BY NAME
HAVING COUNT(PURCHASE) = 3
給出所有名稱,在他的列表中恰好有3個項目。
您需要內部聯接的此查詢:
SELECT T.NAME, T.PURCHASE
FROM TOYSTORE T
JOIN (
SELECT NAME, COUNT(PURCHASE)
FROM TOYSTORE
GROUP BY NAME
HAVING COUNT(PURCHASE) = 3
) I
ON I.NAME = T.NAME
這樣可以解決您的問題嗎? 如果沒有,請告訴我們更多。
問題可能是:如果有人買了2個泰迪熊和1把劍怎么辦? 如果有人購買了所有三件商品,又購買了另一件商品,該怎么辦?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.