从单个表中按最大值过滤掉重复的结果

时间:2014-10-17 08:23:36

标签: mysql sql

我试图通过最大STAMP列过滤掉表中的结果。我需要的结果是每个重复的ID号都要过滤掉,所以我有一个带有最大标记的ID号。

编辑:列定义 -

doe - datetime var - varvarchar(4)latin1_swedish_ci ID - varchar(9)latin1_swedish_ci 邮票 - bigint(20)

以下数据是一个小片段 -

DATE                VAR      ID     STAMP
01/09/2014 00:05    WEBN    13279   212276333136568000
01/09/2014 00:06    WEBN    13084   212276333179962000
01/09/2014 00:07    WEBN    13084   212276333236687000
01/09/2014 00:25    WEBN    13192   212276334356964000
01/09/2014 00:28    WEBN    13433   212276334517114000
01/09/2014 00:29    WEBN    13433   212276334574072000
01/09/2014 00:54    WEBN    13261   212276336085970000
01/09/2014 01:24    WEBN    13208   212276337880800000
01/09/2014 01:26    WEBN    13208   212276337972060000
01/09/2014 01:41    WEBN    13256   212276338901120000
01/09/2014 02:07    WEBN    13225   212276340440626000
01/09/2014 02:28    WEBN    13048   212276341700449000
01/09/2014 02:29    WEBN    13048   212276341789222000
01/09/2014 02:31    WEBN    13217   212276341897262000
01/09/2014 03:21    WEBN    13464   212276344870866000
01/09/2014 03:22    WEBN    13464   212276344970040000
01/09/2014 04:01    WEBN    13486   212276347260517000
01/09/2014 04:02    WEBN    13486   212276347351666000
01/09/2014 05:14    WEBN    13490   212276351690524000
01/09/2014 05:16    WEBN    13490   212276351776728000
01/09/2014 17:55    WEBN    13393   212276397317713000
01/09/2014 18:17    WEBN    13253   212276398658967000

以下查询是我正在使用的内容。

    CREATE TABLE SPC_VARCOLL AS SELECT m.* FROM var_x m 
WHERE m.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-30 23:59:59'
AND m.VAR= 'WEBN' 
AND m.STAMP = (SELECT MAX(m.STAMP) FROM var_x m2 WHERE m2.ID= m.ID) 

它会过滤重复的结果,但似乎也过滤掉非重复的结果?我在新创建的表中只获得了45个结果,我应该更加像1000.

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您正在使用三个过滤器:

WHERE m.DATA BETWEEN ...
m.VAR = 'WEBN'
m.STAMP = <subquery>

这里的问题是您的子查询不会再次应用前两个过滤器。假设你有这个简单的数据集:

DATE                VAR     ID  STAMP
01/09/2014 00:01    WEBN    1   100
01/09/2014 00:05    WEBN    1   101
01/09/2014 00:01    WEBN    2   200
01/09/2014 00:25    WEBN    2   201

现在,如果我们执行您的查询(请注意日期过滤器)

SELECT m.* FROM var_x m 
WHERE m.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-01 00:20:00'
AND m.VAR= 'WEBN' 
AND m.STAMP = (SELECT MAX(m.STAMP) FROM var_x m2 WHERE m2.ID= m.ID)

我们得到以下结果

01/09/2014 00:05    WEBN    1   101

为什么ID 2不在那里?因为它不符合子查询的标准,因为MAX值是“全局”,而您正在寻找过滤的MAX。具体来说,子查询ID = 2的结果是201,但该记录不在过滤的时间范围内(00:00到00:20之间),因此它将被过滤掉。

使用此查询

SELECT m.* FROM var_x m 
WHERE m.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-01 00:20:00'
AND m.VAR= 'WEBN' 
AND m.STAMP = (
    SELECT MAX(m2.STAMP) 
    FROM var_x m2 
    WHERE m2.ID= m.ID
    AND m2.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-01 00:20:00'
    AND m2.VAR= 'WEBN' 
)

应该产生预期的结果。

答案 1 :(得分:0)

我不明白为什么你的查询不起作用。您可以通过以下方式获得预期的结果计数:

SELECT count(*)
FROM var_x m 
WHERE m.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-30 23:59:59'
  AND m.VAR= 'WEBN'
GROUP BY m.ID
;

我使用Oracle 11g及更高版本的另一个解决方案,使用最近的聚合运算符:

SELECT max(m.DATE)  keep (dense_rank last order by m.STAMP) DATE,
       max(m.VAR)   keep (dense_rank last order by m.STAMP) VAR,
       m.ID,
       max(m.STAMP) keep (dense_rank last order by m.STAMP) STAMP
FROM var_x m 
WHERE m.DATE BETWEEN '2014-09-01 00:00:00' AND '2014-09-30 23:59:59'
  AND m.VAR= 'WEBN'
GROUP BY m.ID
;