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)