SQL 检索具有不同序列号的所有记录,在日期范围和计数之间,拒绝代码 = "Low Current"

Posted

技术标签:

【中文标题】SQL 检索具有不同序列号的所有记录,在日期范围和计数之间,拒绝代码 = "Low Current"【英文标题】:SQL Retrieve all records with distinct serialnum, between date range and count reject code = "Low Current" 【发布时间】:2014-11-11 15:17:00 【问题描述】:

表名 = 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"

我已成功找到日期范围并找到具有“低电流”的记录。

无法从不同的 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'

我的结果会给我 计数 = 3

我需要得到 计数 = 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 新手,所以准确的示例和详细的解释非常有帮助。 非常感谢您的帮助。 谢谢, 凯文

【问题讨论】:

【参考方案1】:
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。否则,子查询 返回真。 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';

【讨论】:

这行得通!我有一些疑问。 From tblName t1 // 这会产生什么?这是数据库中的新表吗? (选择 1 // 这是从什么中选择的?你能为初学者推荐一本好的 SQL 书吗?我还有一个问题是这很慢,因为我正在遍历所有可能的故障,其中有 72 个。我在 Qt 中编程C++,有没有办法打破它以加快速度?感谢您的帮助! @Kevin "tblName t1" - 它给表一个别名。别名之所以有用有几个原因: 1)当您从多个表(多个连接)中进行选择时,它们可以帮助区分来自不同表的列; 2)它们可以解决冲突(当多个表具有相同名称的列时。 @Kevin "select 1 // 这是从什么中选择的" - 假设您从表中选择了一些列,假设您有 5 行,然后将所有列替换为值为“1”的列在每一行。这就是 select 1 from tab 返回的内容。你总是可以在你的选择列表中放置任何常量 @Kevin 当我还是个学生的时候,我读了“C.J. Date Introduction to Database Systems”,然后一头扎进了 Oracle。 @Kevin 我添加了另一个查询。但是,如果您的表中有很多不同的日期,我建议您在 TIMESTAMP_ 列上创建一个索引。它应该会加快您的查询速度。【参考方案2】:

也许更容易:

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;

首先,它只选择具有正确日期范围的记录,按序列号对它们进行分组,并将拒绝代码 1 分配给所有序列号,这些序列号的拒绝值不同于“低电流” - 之后我们只需抛出所有行拒绝代码为 1 的距离

【讨论】:

以上是关于SQL 检索具有不同序列号的所有记录,在日期范围和计数之间,拒绝代码 = "Low Current"的主要内容,如果未能解决你的问题,请参考以下文章

SQL从日期范围内的同一表中的不同记录中获取多个项目的总和(ORACLE)

Hive SQL - 检索日期范围中存在的列的不同值

如何在 R 中表示和合并具有*日期范围*的时间序列数据帧?

SQL Server:填写每个实体具有不同日期范围的缺失日期

SQL Server:如何根据最近的日期时间检索所有记录

使用Sub Query中的Left Join检索所有行