SQL 求助 - 计算除特殊情况外的所有序列号
SQL help - count all serialNumbers except those with specific cases
我需要帮助在 where 子句中编写 case 语句。
假设我们有一堆序列号存储在数据库中。
它们以一些字母为前缀来表示它们的组。
这是我需要完成的:
排除所有以 'GIU' 开头的序列号,除非某些条件适用:
- 如果序列号以GIU开头,长度为15个字符,最后4个数字小于5000,则排除,否则包括。
- 如果序列号以GIU开头,长度为16个字符,且后5位小于10000,则排除,否则包含。
例如。应包括 GIU930798246071,因为:以 GIU 开头 -> 15 个字符长 -> 6071 > 5000.
ex2。应该包括 GIU9307982410621,因为它以 GIU 开头 -> 16 个字符长 -> 10621 > 10000.
ex3。应排除 GIU930798243071,因为 15 个字符长 -> 最后 4 位数字 (3071) < 5000。
如果我想 运行 一个查询来计算这些结果,我试过:
select count(serialNum)
FROM serialNumbers
WHERE serialNum not like (
case when LEN(serialNum) = 15 and SUBSTRING(serialNum, 1, 3) = 'GIU' and RIGHT(serialNum, 4) < 5000 then 'GIU%'
when LEN(serialNum) = 16 and SUBSTRING(serialNum, 1, 3) = 'GIU' and RIGHT(serialNum, 5) < 10000 then 'GIU%' end)
如果这些条件适用,我正在尝试将 case 语句的结果附加到 not like 语句中。
运行 查询 returns 为空,所以我知道部分情况会破坏整个查询。
此外,还有其他序列号以其他字母开头,它也应该计算在内。
我基本上只需要它来计算除这些特定情况下以 GIU 开头的序列号之外的所有序列号。
感谢任何帮助。
有时候事情可能比你想象的要简单。我重新安排了您的 WHERE 子句以匹配您在描述中提供的规格。我得到这样的东西。
select count(serialNum)
FROM serialNumbers
WHERE
serialNum not like 'GIU%' or
(LEN(serialNum) = 15 and CAST(RIGHT(serialNum, 4) AS INT) >= 5000) or
(LEN(serialNum) = 16 and CAST(RIGHT(serialNum, 5) AS INT) >= 10000)
这有帮助吗?
请注意,我明确地将序列号的最后 4 或 5 位转换为整数。如果这些位置不是数字,我假设查询将失败。这种情况也有解决方案,但为了清楚起见,我在这里省略了它们。
编辑:
假设上述查询逻辑正确,还有另一种解决方案。
大于或等于 5000 的 4 位数字的形式为 5nnn
、6nnn
、7nnn
、8nnn
或 9nnn
。大于或等于 10000 的 5 位数字不以 0 开头。
在这些情况下使用 LIKE 模式匹配,您也可以使用以下查询:
select count(serialNum)
FROM serialNumbers
WHERE
serialNum not like 'GIU%' or
(LEN(serialNum) = 15 and serialNum like '%[56789]___') or
(LEN(serialNum) = 16 and serialNum like '%[^0]____')
请注意,我在此处的 LIKE 模式中使用了下划线来匹配任何单个字符。我只是假设它们实际上是数字。
编辑 2:
对不起。重新阅读您的问题,我可能以错误的方式检查了最后一位数字。已修复。
因此,您可以做一个专栏来确认您正在寻找(或不寻找)什么。一旦你确认了,那就去做吧。通过稍微改变 Bart 提供的内容,您需要在条件中明确包含“GIU”
你不想要什么...
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 15
AND CAST(RIGHT(serialNum, 4) AS INT) < 5000 )
OR
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 16
AND CAST(RIGHT(serialNum, 5) AS INT) < 10000 )
因此,如果 where 子句是上述内容,您将只能获得排除领域中的那些。所以要反转这个,
WHERE NOT ( above condition1 or condition2 )
因此
WHERE
NOT (
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 15
AND CAST(RIGHT(serialNum, 4) AS INT) < 5000 )
OR
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 16
AND CAST(RIGHT(serialNum, 5) AS INT) < 10000 )
)
我需要帮助在 where 子句中编写 case 语句。
假设我们有一堆序列号存储在数据库中。 它们以一些字母为前缀来表示它们的组。
这是我需要完成的:
排除所有以 'GIU' 开头的序列号,除非某些条件适用:
- 如果序列号以GIU开头,长度为15个字符,最后4个数字小于5000,则排除,否则包括。
- 如果序列号以GIU开头,长度为16个字符,且后5位小于10000,则排除,否则包含。
例如。应包括 GIU930798246071,因为:以 GIU 开头 -> 15 个字符长 -> 6071 > 5000.
ex2。应该包括 GIU9307982410621,因为它以 GIU 开头 -> 16 个字符长 -> 10621 > 10000.
ex3。应排除 GIU930798243071,因为 15 个字符长 -> 最后 4 位数字 (3071) < 5000。
如果我想 运行 一个查询来计算这些结果,我试过:
select count(serialNum)
FROM serialNumbers
WHERE serialNum not like (
case when LEN(serialNum) = 15 and SUBSTRING(serialNum, 1, 3) = 'GIU' and RIGHT(serialNum, 4) < 5000 then 'GIU%'
when LEN(serialNum) = 16 and SUBSTRING(serialNum, 1, 3) = 'GIU' and RIGHT(serialNum, 5) < 10000 then 'GIU%' end)
如果这些条件适用,我正在尝试将 case 语句的结果附加到 not like 语句中。
运行 查询 returns 为空,所以我知道部分情况会破坏整个查询。
此外,还有其他序列号以其他字母开头,它也应该计算在内。
我基本上只需要它来计算除这些特定情况下以 GIU 开头的序列号之外的所有序列号。
感谢任何帮助。
有时候事情可能比你想象的要简单。我重新安排了您的 WHERE 子句以匹配您在描述中提供的规格。我得到这样的东西。
select count(serialNum)
FROM serialNumbers
WHERE
serialNum not like 'GIU%' or
(LEN(serialNum) = 15 and CAST(RIGHT(serialNum, 4) AS INT) >= 5000) or
(LEN(serialNum) = 16 and CAST(RIGHT(serialNum, 5) AS INT) >= 10000)
这有帮助吗?
请注意,我明确地将序列号的最后 4 或 5 位转换为整数。如果这些位置不是数字,我假设查询将失败。这种情况也有解决方案,但为了清楚起见,我在这里省略了它们。
编辑:
假设上述查询逻辑正确,还有另一种解决方案。
大于或等于 5000 的 4 位数字的形式为 5nnn
、6nnn
、7nnn
、8nnn
或 9nnn
。大于或等于 10000 的 5 位数字不以 0 开头。
在这些情况下使用 LIKE 模式匹配,您也可以使用以下查询:
select count(serialNum)
FROM serialNumbers
WHERE
serialNum not like 'GIU%' or
(LEN(serialNum) = 15 and serialNum like '%[56789]___') or
(LEN(serialNum) = 16 and serialNum like '%[^0]____')
请注意,我在此处的 LIKE 模式中使用了下划线来匹配任何单个字符。我只是假设它们实际上是数字。
编辑 2:
对不起。重新阅读您的问题,我可能以错误的方式检查了最后一位数字。已修复。
因此,您可以做一个专栏来确认您正在寻找(或不寻找)什么。一旦你确认了,那就去做吧。通过稍微改变 Bart 提供的内容,您需要在条件中明确包含“GIU”
你不想要什么...
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 15
AND CAST(RIGHT(serialNum, 4) AS INT) < 5000 )
OR
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 16
AND CAST(RIGHT(serialNum, 5) AS INT) < 10000 )
因此,如果 where 子句是上述内容,您将只能获得排除领域中的那些。所以要反转这个,
WHERE NOT ( above condition1 or condition2 )
因此
WHERE
NOT (
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 15
AND CAST(RIGHT(serialNum, 4) AS INT) < 5000 )
OR
( left( serialNum, 3 ) = 'GIU'
AND LEN(serialNum) = 16
AND CAST(RIGHT(serialNum, 5) AS INT) < 10000 )
)