2016-01-06 129 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 

这种方式任意划分历法转换成基于一个出发点的三阶会阻塞。

将有可能有连续的日期,形成第一个块的结尾和下一个的开始。我怀疑你是否想要这样,我会看看我能否找到能够提供更好平衡的东西。

您遗漏的过滤标准有多复杂?