2014-04-19 126 views
1
SELECT db.people.first_name, 
db.people.last_name, 
db.people.email 

FROM db.convert, db.people 
HAVING COUNT(db.convert.year) > 1 
WHERE db.convert.email = db.people.email 
AND (SUBSTRING(db.convert.gross, 1, 2) != '$-') 
GROUP BY db.people.email 

此查詢工作正常沒有HAVING語句,但我需要它僅選擇在表中多條記錄不同年份的電子郵件。所以2011年,2012年,2013年使用具有隻選擇多個記錄特定領域

另外我希望它顯示該電子郵件和姓氏只有一次,不同?

當我添加有語句的查詢不運行

+1

HAVING不應該在組之後還是不重要? – Devon

+0

真棒查詢現在工作,沒有更多的錯誤。 –

+0

很高興它的工作,我不得不迅速恢復自我。你不需要像我建議你的方法那樣使用count(*),只需要將GROUP BY後面的HAVING。我添加了一個答案。 – Devon

回答

1

HAVING是基於GROUP BY條件。所以它需要在GROUP BY之後。

GROUP BY db.people.email HAVING COUNT(db.convert.year) > 1 

由於奧利·瓊斯和戈登·利諾夫建議,如果你每年有超過一個記錄每個人,那麼你將要使用DISTINCT的COUNT這樣你就不會計算,每年一次以上:

GROUP BY db.people.email HAVING COUNT(DISTINCT db.convert.year) > 1 
+1

OP可能需要'COUNT(DISTINCT db.convert.year)> 1'來滿足要求,我讀它的方式。 –

+0

@OllieJones是的,好點,這個查詢假定db.convert.year是一個獨特的列。 – Devon

2

下面是編寫這個查詢一個更好的辦法:

SELECT p.first_name, p.last_name, p.email 
FROM db.convert c join 
    db.people p 
    on c.email = p.email 
WHERE c.gross not like '$-%' 
GROUP BY p.email 
HAVING COUNT(c.year) > 1; 

除了與having固定的語法問題,我也:

  • 引入表別名(cp)使查詢更具可讀性。
  • where子句中使用正確的連接語法而不是隱式連接。
  • 使用like而不是substring(),所以比較可以利用索引。

另外,COUNT(c.year)可能不會做你想要的。這可能與COUNT(c.gross),COUNT(c.email)COUNT(*), because it counts the number of non-NULL values in年相同。我不知道你想要什麼,但如果你想有至少兩年的記錄,電子郵件,則表達式應該是:

HAVING COUNT(DISTINCT c.year) > 1 
+0

好的補充。別名和'不喜歡'我同意,但是有什麼特別的錯誤與隱式連接或僅僅是爲了組織它的用戶,讓他們知道連接是什麼? – Devon

+0

@Devon。 。 。讓我們說,大多數使用SQL的人都認爲隱式聯接是非常糟糕的風格。它們受到每個數據庫的支持,它們都是ANSI標準的正式組成部分,但它們很難維護,表達性較差(不支持外連接),更難以閱讀,並且更容易出錯。 –

+0

這正是我所需要的,你預先考慮了我對DISTINCT的需求。因爲我想選擇多個不同的年份。 –

0

你有兩個要求,它似乎。 (我假設一封電子郵件唯一標識一個人。)

一,給出一個人的名字和電子郵件列表。

二,顯示您在convert表中出現在多個不同年份的人。

該查詢可以滿足第二個要求。它通過電子郵件計算出不同的轉換年份,並將其轉換爲只有一個轉換年的轉換年。正如有人在評論中提到的,HAVING應該在GROUP BY之後。

SELECT COUNT(DISTINCT year) AS years, email 
    FROM db.convert 
WHERE SUBSTRING(gross, 1, 2) !- '$-' 
GROUP BY email 
HAVING COUNT(DISTINCT year) > 1 

然後我們可以使用它作爲一個子查詢(虛擬表)去獲得人的名字,如下:

SELECT p.first_name, 
     p.last_name, 
     p.email 
    FROM db.people AS p 
    JOIN (
     SELECT COUNT(DISTINCT year), email 
      FROM db.convert 
     WHERE SUBSTRING(gross, 1, 2) !- '$-' 
     GROUP BY email 
     HAVING COUNT(DISTINCT year) > 1 
     ) AS years ON p.email = years.email 
ORDER BY p.last_name, p.first_name, p.email 

它使用的結構化查詢語言結構部分正是爲了從你的表中指定你需要的東西。

通過這種方式構建查詢,可以逐步調試。在表連接中使用COUNT()或其他聚合函數時,您必須小心,因爲由於組合方式的加入,您可能會獲得比您討價還價更多的行。