2013-05-31 164 views
0

我正在嘗試創建一個執行以下操作的SQL語句,但顯然會失敗。複雜SQL選擇語句

選擇來自它基於下面的準則的視圖和過濾器的所有信息:

  1. 如果給定的字段「CUSTOMER_NUMBER」存在於表格中的任何點
  2. 然後檢查內的任何重複最近30天
  3. 然後輸出按客戶編號分組的所有不同customer_numbers
  4. 有一個計數,以便我可以看到一個項目重複了多少次。

所以今天使用作爲我們當前的日期說,我在我的表中的下列數據項:

customer_number, date 
111111, 2013-01-01 
111111, 2013-05-05 
222222, 2013-01-07 
222222, 2013-03-19 
333333, 2013-05-15 
333333, 2013-05-30 

我希望我的SELECT語句返回如下:

customer_number, date, count 
111111, 2013-01-01, 2 
333333, 2013-05-15, 2 

而且客戶222222將不會顯示,因爲他在過去30天內沒有出現。

這裏是關於我試圖弄清楚這一點。它僅返回當前月份的數據。

SELECT *, COUNT(customer_number) 
FROM red_flags 
WHERE dealer_id = '75' AND date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() 
GROUP BY customer_number 
HAVING COUNT(customer_number) > 1 

我已經融化我的大腦試圖找出如何或者如果這甚至有可能做一個查詢任何幫助將不勝感激!

+0

如何選擇日期 - 是否總是選擇MIN()? – sgeddes

+0

@sgeddes日期應該是它第一次出現在表格中。 – bmanhard

回答

1

這裏是如何做到這一點使用JOIN

select r.customer_number, count(*) ct, min(date) minDate 
from red_flags r 
join (select distinct customer_number 
     from red_flags 
     where dealer_id = '75' 
     and date between CURDATE() - INTERVAL 30 DAY and CURDATE()) x 
ON r.customer_number = x.customer_number 
group by customer_number 
HAVING ct > 1 

SQLFIDDLE

+0

這工作完美,超快感謝噸! – bmanhard

+0

爲什麼MySQL在優化IN時如此糟糕?在閱讀更多內容之前,我沒有意識到這一點。感謝您的關注。順便說一句 - 我認爲我編輯的內容可能是最好的解決方案。親切的問候! – sgeddes

+0

@sgeddes看看EXPLAIN - 它傾向於使用錯誤的索引。它不是選擇子查詢中的項目,然後將它們編入主表中,而是掃描整個主表,然後索引到子查詢中。 – Barmar

1

像這樣的東西應該適合你 - 它使用子查詢來找出哪些客戶在過去30天內被標記過。然後它使用COUNT獲得總數,並使用MIN獲得第一個日期。

SELECT customer_number, COUNT(1), MIN(date) minDate 
FROM red_flags 
WHERE customer_number IN (
    SELECT customer_number 
    FROM red_flags 
    WHERE dealer_id = '75' 
     AND date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() 
) 
GROUP BY customer_number 

如果你只關心那些有多個記錄,你可以添加HAVING子句。

BTW,使用BETWEEN的日期要小心。我更喜歡明確地使用> =和< =來獲得更多控制。


編輯 - 也許是最簡單的解決方案,使用次數與CASE:

SELECT customer_number, COUNT(1), MIN(date) minDate 
FROM red_flags 
GROUP BY customer_number 
HAVING COUNT(CASE WHEN date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() THEN 1 END) > 0 
+0

似乎工作,它採取我的數據庫~45秒來解析這個查詢,有沒有什麼辦法來加速它呢? – bmanhard

+0

@bmanhard - 哇,這是很長的時間。你有在customer_id字段的索引嗎? – sgeddes

+0

我也只關心有多個記錄的項目,我在GROUP BY下面添加了HAVING COUNT(customer_number)> 1,它不再返回記錄。 – bmanhard