2016-01-06 160 views
0

好的,我有一張表,其中包括:名稱,c_id,日期。SQL Group按日期排序

該表中的某些條目符合某些標準,我可以使用WHERE有效選擇,所以這不是問題。

我想什麼,然後,是一種分組的,除了名稱和C_ID列,三個日期的:日期 - 1,日期,日期+ 1。換句話說,我希望輸出的每一行代表具有相同名稱和c_id作爲某個相關條目的所有條目,並且該條目發生在該條目之前的一天之前(包括其自身)。

我該怎麼做呢?

--edit:

(EDIT2:起源表應該是Table 1和表2的INNER JOIN ON Table1.id = Table2.id)

樣本數據:

Table1: 
    id | c_id |  date  | other stuff 
----------------------------------------------------- 
    01 | abc | 2015/12/09 | whatever 
    02 | abc | 2015/12/09 | whatever 
    03 | abc | 2015/12/10 | relevant criterion 
    04 | abc | 2015/12/11 | whatever 
    05 | def | 2015/11/15 | whatever 
    06 | def | 2015/11/16 | relevant criterion 
    07 | abc | 2015/11/17 | whatever 
    08 | mnc | 2016/01/02 | whatever 
    09 | mnc | 2016/01/02 | whatever 
    10 | mnc | 2016/01/03 | whatever 
    11 | mnc | 2016/01/03 | whatever 
    12 | mnc | 2016/01/03 | whatever 
    13 | mnc | 2016/01/04 | relevant criterion 
    14 | mnc | 2016/01/05 | whatever 
    15 | mnc | 2016/01/05 | whatever 
    16 | mnc | 2016/01/06 | whatever 

Table2: 
    id | Name | other stuff 
-------------------------------------- 
    01 | John | whatever 
    02 | John | whatever 
    03 | John | whatever 
    04 | John | whatever 
    05 | Mary | whatever 
    06 | Mary | whatever 
    07 | Mary | whatever 
    08 | Alice | whatever 
    09 | Alice | whatever 
    10 | Alice | whatever 
    11 | Alice | whatever 
    12 | Alice | whatever 
    13 | Alice | whatever 
    14 | Alice | whatever 
    15 | Alice | whatever 
    16 | Alice | whatever 

樣品所需的輸出:

Name | c_id | pivot_date | count 
------------------------------------------ 
    John | abc | 2015/12/10 | 4 
    Mary | def | 2015/11/16 | 2 
    Alice | mnc | 2016/01/04 | 6 

(該pivot_date部分沒有特別的必要的一個與相關的標準,所涉及的日期中的任何一個都好)

+1

你可以發佈你到目前爲止嘗試過的SQL嗎? – Haymaker

+0

沒有聚合的'GROUP BY'幾乎沒用。你確定要'GROUP BY'嗎? - 無論如何,您都可以使用自加入來匹配您想要的記錄。 – JimmyB

+0

我不確定我想分組!我很確定我想要的結果,但我並不特別喜歡得到它們的任何方式。我不確定自連接如何找到匹配的記錄?我正在查找的條目通常會在前幾天和第二天之間有幾十條記錄。 (和@Haymaker:我還沒有嘗試過任何東西,我甚至不知道如何開始!) –

回答

0

更新了新的樣本數據:

SELECT t.name, t.c_id, t.date pivot_date, COUNT(*) count 
    FROM record t 
    JOIN record t2 
     ON t2.name = t.name 
    AND t2.c_id = t.c_id 
    AND t2.date >= t.date - INTERVAL 1 DAY   
    AND t2.date <= t.date + INTERVAL 1 DAY 
    WHERE t.other_stuff = 'relevant criterion' 
GROUP BY t.name, t.c_id, t.date 

See SQLFiddle

-

更新了新的樣本數據:

SELECT t2.name, t1.c_id, t1.date pivot_date, COUNT(*) count 
    FROM table1 t1 
    JOIN table1 to1 
     ON to1.c_id = t1.c_id 
    AND to1.date >= t1.date - INTERVAL 1 DAY   
    AND to1.date <= t1.date + INTERVAL 1 DAY 
    JOIN table2 
     ON t2.id = t1.id 
    WHERE t1.other_stuff = 'relevant criterion' 
GROUP BY t2.name, t1.c_id, t1.date 
+0

如果記錄是(Table1 tk INNER JOIN Table2 tm ON tk.id = tm.id)?只是替換它給我一個語法錯誤。 –

+0

@PedroCarvalho應該是(SELECT * FROM Table1 tk INNER JOIN Table2 tm ON tk.id = tm.id),但你可能不需要全部。 – Arth

+0

這擺脫了語法錯誤,但得到了一個「重複列c_id」錯誤。 –

0

這是一種方式:

@dt := '2015-12-10' 

SELECT Name , c_id, MAX(`date`) maxdate, COUNT(*) countof 
FROM table1 
WHERE date >= @dt - INTERVAL 1 DAY AND `date` < @dt + INTERVAL 2 DAY 
GROUP BY Name , c_id 

注日期列可以是MIN(日期)作爲替代

+0

看起來它只會在特定的日子裏向我顯示一個結果? –

+0

它與「Sample desired output」非常相似,是不是你想要的 –

+0

是的,但是該樣本期望的輸出只是其中一個應該是成百上千個或其他數千個其他名稱的輸出列表中的一個name-c_id日期行,有許多日期符號綁定到相同的名稱c_id對多次。 –

0

我不得不使用分析LAG/LEAD函數Oracle中建立這個。我不知道你是否能在MYSQL模擬這些功能(看here仿真)

table1是你的數據

with 
relevant as 
(
select * 
    from (
    select 
     nm, 
     c_id, 
     stuff, 
     dt, 
     lag(dt,1) over (order by nm, dt, c_id) prev, 
     lead(dt,1) over (order by nm, dt, c_id) nxt 
    from table1) 
where stuff = 'relevant criterion' 
) 
select 
    d.nm, 
    d.c_id, 
    to_char(d.dt,'DD-MON-YYY') dt, 
    d.stuff, 
    count(*) over (partition by d.nm, d.c_id) cnt 
    from table1 d 
where (d.dt in (select rp.prev from relevant rp where d.nm = rp.nm and d.c_id = rp.c_id) 
     OR 
     d.dt in (select rn.nxt from relevant rn where d.nm = rn.nm and d.c_id = rn.c_id ) 
     OR 
     d.dt in (select rn.dt from relevant rn where d.nm = rn.nm and d.c_id = rn.c_id ) 
    ) 
; 

結果:

NM C_ID DT STUFF CNT 
Alice mnc 03-JAN-016 whatever 6 
Alice mnc 03-JAN-016 whatever 6 
Alice mnc 03-JAN-016 whatever 6 
Alice mnc 05-JAN-016 whatever 6 
Alice mnc 04-JAN-016 relevant criterion 6 
Alice mnc 05-JAN-016 whatever 6 
John abc 11-DEC-015 whatever 4 
John abc 10-DEC-015 relevant criterion 4 
John abc 09-DEC-015 whatever 4 
John abc 09-DEC-015 whatever 4 
Mary def 15-NOV-015 whatever 2 
Mary def 16-NOV-015 relevant criterion 2 

您可以通過創建過濾上述結果此查詢爲視圖並添加where stuff = 'relevant criterion'篩選條件

NM C_ID DT STUFF CNT 
Alice mnc 04-JAN-016 relevant criterion 6 
John abc 10-DEC-015 relevant criterion 4 
Mary def 16-NOV-015 relevant criterion 2 
0

這是一種天真的做法。這類型的作品:

select t2.Name, t1.c_id, min(t1.Date) as pivot_date, count(*) as cnt 
from Table1 t1 inner join Table2 t2 on t2.id = t1.id 
where <criteria...> 
group by t2.Name, t1.c_id, datediff(t1.Date, '2015-01-01') div 3 

這種方式任意劃分曆法轉換成基於一個出發點的三階會阻塞。

將有可能有連續的日期,形成第一個塊的結尾和下一個的開始。我懷疑你是否想要這樣,我會看看我能否找到能夠提供更好平衡的東西。

您遺漏的過濾標準有多複雜?