SQL检索具有不同serialnum的所有记录,在日期范围和计数拒绝代码之间="低电流"

时间:2014-11-11 15:17:00

标签: sql oracle

表名= tblName

列名:

SERIALNUM    TIMESTAMP_                 REJECT          .......
sn1         10/13/2014  7:30:00 AM      Low Current
sn1         10/14/2014  5:29:23 AM      High Current
sn1         10/14/2014  5:31:00 AM      Low Current
sn2         10/14/2014  5:33:20 AM      Low Current
sn2         10/14/2014  5:44:00 AM      Low Current
sn3         10/14/2014  5:50:00 AM      Low Current
sn3         10/15/2014  8:00:00 AM      Low Current

我想在2014年10月14日找到明显的SERIALNUM并且有一个REJECT =" Low Current"

我成功找到了日期范围,并找到了" Low Current"。

什么不起作用是从不同的SERIALNUM中选择。以下脚本在满足其他条件后计算。

我需要它来选择日期范围之间的不同SERIALNUM并包含REJECT =" Low Current"并返回它发现的数量。

    SELECT COUNT(DISTINCT SERIALNUM) FROM tblName 
WHERE TO_DATE('10/14/2014 00:00:00', 'MM/DD/YYYY HH24:MI:SS') <= TIMESTAMP_ AND 
TIMESTAMP_ < TO_DATE('10/14/2014 23:59:59', 'MM/DD/YYYY HH24:MI:SS') 
AND REJECT LIKE 'Low Current'

我的结果会给我 count = 3

我需要得到 count = 2

sn1         10/13/2014  7:30:00 AM      Low Current   // This is outside of date range, Don't Count
sn1         10/14/2014  5:29:23 AM      High Current  // This is different REJECT code, Don't Count
sn1         10/14/2014  5:31:00 AM      Low Current   // This is 2nd time sn1 run,      Don't Count
sn2         10/14/2014  5:33:20 AM      Low Current   // This meets all criteria        Count
sn2         10/14/2014  5:44:00 AM      Low Current   // This is 2nd time sn2 run,      Don't Count
sn3         10/14/2014  5:50:00 AM      Low Current   // This meets all criteria        Count
sn4         10/15/2014  8:00:00 AM      Low Current   // This is outside of date range, Don't Count

我是SQL的新手,所以确切的例子和详细的解释都非常有用 非常感谢您的帮助 谢谢, 凯文

2 个答案:

答案 0 :(得分:0)

SELECT COUNT(DISTINCT SERIALNUM)
FROM tblName t1
WHERE TO_DATE('10/14/2014 00:00:00', 'MM/DD/YYYY HH24:MI:SS') <= TIMESTAMP_ 
AND TIMESTAMP_ <  TO_DATE('10/14/2014 23:59:59', 'MM/DD/YYYY HH24:MI:SS') 
AND REJECT LIKE 'Low Current'
AND NOT EXISTS (select 1 from tblName t2 
                 where t2.SERIALNUM = t1.SERIALNUM 
                   and t2.REJECT != 'Low Current');
  

EXISTS关键字测试子查询中是否存在任何行。   如果没有找到行,则答案为FALSE。否则,子查询   返回TRUE。 NOT EXISTS反转结果。

     

执行整个子查询,即使EXISTS只需要知道   子查询是否返回任何行 - 因此请注意使用EXISTS   使用返回大量行的子查询。值得注意的是   这种查询有时被称为“半连接”。一个   semijoin是一个使用EXISTS关键字进行比较的SELECT语句   表中的行与另一个表中的行。

(select 1 from tblName t2 
 where t2.SERIALNUM = t1.SERIALNUM 
   and t2.REJECT != 'Low Current')

这是一个相关的子查询。相关因为它取决于父查询(条件t2.SERIALNUM = t1.SERIALNUM)。没有父查询,相关子查询不能存在。

据我了解,您只需要计算仅包含“低电流”的SERIALNUM。拒绝价值。 EXISTS有助于检查这一点。

替代查询:

SELECT sum(1) FROM
    (SELECT COUNT(DISTINCT REJECT) number_of_unique_rejects, 
            max(REJECT) as reject
    FROM tblName t1
    WHERE TO_DATE('10/14/2014 00:00:00', 'MM/DD/YYYY HH24:MI:SS') <= TIMESTAMP_ 
    AND TIMESTAMP_ <  TO_DATE('10/14/2014 23:59:59', 'MM/DD/YYYY HH24:MI:SS') 
    GROUP BY SERIALNUM)
WHERE number_of_unique_rejects = 1 and reject = 'Low Current';

答案 1 :(得分:0)

可能更容易:

SELECT * FROM
 ( SELECT serialnum
         ,MAX(CASE reject WHEN 'Low Current' THEN 0 ELSE 1 END) reject_code
     FROM tblName
    WHERE TRUNC(timestamp_) = TO_DATE('2014-10-14', 'YYYY-MM-DD')
    GROUP BY serialnum
 ) t
WHERE t.reject_code= 0;

首先,它仅选择具有正确日期范围的记录,按serialnum对它们进行分组,并为所有序列号分配reject_code,其拒绝值不同于“低电流”。 - 之后我们简单地抛弃所有行的reject_code为1