簡體   English   中英

使用自聯接的SQL查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM