[英]SQL queries using self-join
我可以簡單地選擇,加入,更新查詢。 但這對我來說似乎有點困難(我正在學習)。
客戶有一個這樣的表(使用Mysql )(我沒有控制他的數據庫模式,我不能為他創建客戶表。我只需要創建一些客戶報告)。
+-----------+--------------+--------------------------+
|Transaction|Customers name|Customers email |Set |
+-----------+--------------+--------------------------+
| 1 | John | jo@gmail.com | blue |
| 2 | Mary | ma@gmail.com | green |
| 3 | Paul | pa@gmail.com | red |
| 4 | JOHN G. | jo@gmail.com | green |
| 5 | Paul Simon | pa@gmail.com | blue |
+-----------+--------------+--------------------------+
如您所見,客戶每筆交易都自由輸入其姓名。 這顯然可以帶來更多的客戶,但是電子郵件字段是唯一的。
我需要制作這些報告(所有報告均由他購買的商品-“設置”字段決定):
1)AND搜索(例如“ blue”和“ green”)購買了“ this”和“ that”集的客戶。 我需要得到這樣的結果:
|John | jo@gmail.com |
或這樣(就像我說的那樣,John可以在每次交易中以不同的方式輸入他的名字。如果該電子郵件是唯一的,那么可以):
|JOHN G. | jo@gmail.com |
2)OR搜索(例如“藍色”或“紅色”)需要獲取此信息:
|John | jo@gmail.com |
|Paul | pa@gmail.com |
或這個:
|John | jo@gmail.com |
|Paul Simon| pa@gmail.com |
3)買了一套,但沒有買另一套(例如“綠色”但沒有“藍色”)
|Mary | ma@gmail.com |
有人知道怎么做嗎? 我相信這可以通過某種“自我加入”來實現。 但是,由於我只是一個初學者,所以我不知道該如何解決。
對於第一個查詢-我在這里使用子查詢
select name,email from customer c where Set = 'blue' and c.email = (select email from customer where Set = 'green' and email = c.email);
對於第二個查詢-簡單或條件就足夠了
select * from customer where Set = 'green' or Set = 'blue' group by email ;
對於第三個查詢-(根據您的要求,它可以解決,它可以基於這樣的方法,例如應該只有1條記錄,並且該記錄應具有在輸入中提到的Set值)
select * from customer group by email having count(pset)= 1 and pset like 'green';
顯然,一個人可以購買這個或那個套裝,我想甚至有一個人可以在以后的交易中再次購買相同的套裝。
因此,您需要每個人的信息。 最簡單的方法是通過按人員分組( GROUP BY
)來匯總您的數據。 然后,您在HAVING
子句中檢查匯總:客戶是否通過設置X和/或y?
查詢1:
select email, name
from transactions
group by email
having max(case when set = 'blue' then 1 else 0 end) = 1
and max(case when set = 'green' then 1 else 0 end) = 1;
查詢2:
select email, name
from transactions
group by email
having max(case when set = 'blue' then 1 else 0 end) = 1
or max(case when set = 'red' then 1 else 0 end) = 1;
查詢3:
select email, name
from transactions
group by email
having max(case when set = 'green' then 1 else 0 end) = 1
and max(case when set = 'blue' then 1 else 0 end) = 0;
通過這些查詢獲得的名稱只是任意選擇的匹配名稱之一。 這在MySQL中很特別。 在標准SQL中,這是不允許的。 無論如何,無論是MySQL還是標准SQL,您都可以使用MIN(name)
或MAX(name)
始終按字母順序獲取第一個或最后一個。
順便說一句: CASE WHEN
表達式是標准SQL。 但是,MySQL具有附加的特殊布爾處理:一個真表達式的值為1,一個假表達式的值為0。因此,在MySQL中,您可以簡單地將max(set = 'green') = 1
而不是max(case when set = 'green' then 1 else 0 end) = 1
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.