SQL Case Statement numeric and varcha
SQL
我想将小学分配给 9 年级以下和 9 年级及以上的学年,而 Preschool 是相同的
- 请明确说明您的问题
- 始终为 SQL 中的字符串分配长度(例如 VARCHAR(20),而不是 VARCHAR) – 否则,SQL 会将您的字符串截断为单个字符。无论如何,您的问题可以通过 CASE WHEN ISNUMERIC(Class_Year) = 1 THEN CASE WHEN Class_Year < 9 THEN ‘Primary’ ELSE ‘Secondary’ END ELSE Class_Year END AS SchType 之类的方法解决
- 为了提高您的问题的质量,请在问题中包含一个示例数据表作为文本。请将其格式化为代码段(突出显示代码并单击文本输入区域上方的 {} 按钮,或将每行缩进四个空格)。请将您的代码复制为问题中的文本,格式为代码段。请包括另一个表格,显示输出应如何显示。
- 如果您将变量定义为 VARCHAR 它将与 varchar(1) 相同 – 所以在您的代码中 @sec 的值实际上只是 S
请尝试以下…
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
SELECT Student_Subject_Type_Desc,
Class_Year, CASE WHEN Class_Year = ‘PreSchool’ THEN ‘PreSec’ WHEN Class_Year = ‘Voc Yr1’ THEN ‘Voc_Yr1’ WHEN Class_Year = ‘Voc Yr2’ THEN ‘Voc_Yr2’ WHEN ISNUMERIC( Class_Year ) <> 1 THEN NULL WHEN CAST( Class_Year AS INT ) < 9 THEN ‘Primary’ ELSE ‘Secondary’ END AS SchType FROM FILNA.dbo.VIEW_FILNA_STUDENTS_SUBJECT ORDER BY Student_Subject_Type_Desc LIMIT 1000 |
CASE 语句基于由字符串值组成的Class_Year。此值将等效于一个数字、几个可接受的字符串之一(即 PreSchool、Voc Yr1 和 Voc Yr2),或者在某些方面无效。
我首先测试了 Class_Year 是否等于可接受的字符串之一。消除这些可能性后,测试 Class_Year 的值是否代表一个数字变得更加容易。我使用 ISNUMERIC( Class_Year ) <> 1 来测试 Class_Year 是否不代表数字并在这种情况下返回值 NULL。如果 Class_Year 的值确实表示一个数字,则根据该数字的值返回 Primary 或 Secondary,这是我通过将 Class_Year 的值转换为 INT 获得的。
请注意,从您的问题中不清楚如何处理 0 的 Class_Year 值、负数、太大的数字和非整数等效实数,所以我假设它们不会发生或不会发生需要进行测试。如果确实需要对其进行测试,请修改您的问题以说明这一点。另外,如果您希望我测试太大的数字,请说明最大有效数字是多少。
附录
至于您第二条评论中的第二条语句,您提供的代码是…
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
SELECT Student_Subject_Type_Desc,
Class_Year, CASE WHEN Class_Year = ‘PreSchool’ THEN ‘PreSec’ WHEN Class_Year = ‘Voc Yr1’ THEN ‘Voc_Yr1’ WHEN Class_Year = ‘Voc Yr2’ THEN ‘Voc_Yr2’ WHEN ISNUMERIC( Class_Year ) <> 1 THEN NULL WHEN CAST( Class_Year AS INT ) < 9 THEN ‘Primary’ ELSE ‘Secondary’ END AS SchType FROM [FILNA].[dbo].[Student_Subject_Desc] WHERE SchType = ‘Primary’ ORDER BY Student_Subject_Type_Desc |
因为 SchType 是我们使用 CASE 语句从应用 WHERE 子句后允许的字段创建的字段,所以我们的 WHERE 子句将无法引用它。解决此问题的一种方法是将我的回答开头的语句用作 SELECT 语句的子查询,该语句将返回受 WHERE 子句约束的所有字段。例如…
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SELECT Student_Subject_Type_Desc,
Class_Year, SchType FROM ( SELECT Student_Subject_Type_Desc, Class_Year, CASE WHEN Class_Year = ‘PreSchool’ THEN ‘PreSec’ WHEN Class_Year = ‘Voc Yr1’ THEN ‘Voc_Yr1’ WHEN Class_Year = ‘Voc Yr2’ THEN ‘Voc_Yr2’ WHEN ISNUMERIC( Class_Year ) <> 1 THEN NULL WHEN CAST( Class_Year AS INT ) < 9 THEN ‘Primary’ ELSE ‘Secondary’ END AS SchType FROM FILNA.dbo.VIEW_FILNA_STUDENTS_SUBJECT ) AS SchTypeFinder WHERE SchType = `Primary` ORDER BY Student_Subject_Type_Desc LIMIT 1000 |
但是,这比将语句更改为这种形式效率低…
1
2 3 4 5 6 7 8 |
SELECT Student_Subject_Type_Desc,
Class_Year, ‘Primary’ AS SchType FROM [FILNA].[dbo].[Student_Subject_Desc] WHERE ISNUMERIC( Class_Year ) = 1 AND CAST( Class_Year AS INT ) < 9 ORDER BY Student_Subject_Type_Desc LIMIT 1000 |
这只会 SELECT 记录其中 Class_Year 表示小于 9 的数字,即只有那些符合 SchType = ‘Primary’ 条件的记录。这消除了对 CASE 语句的任何需求,并使我们能够始终为 SchType 返回 Primary。
如果您有任何问题或意见,请随时发表相应的评论。
进一步阅读
使用 sql 查询将字符串转换为 int(关于将字符串转换为 INT)
https://docs.microsoft.com/en-us/sql/t-sql/functions/isnumeric-transact-sql(关于 ISNUMERIC() 函数)
- 消息 4145,级别 15,状态 1,第 7 行 在预期条件的上下文中指定的非布尔类型表达式,靠近 \\’THEN\\’。
- 选择 [Student_Subject_Type_Desc],[Class_Year], \\\\t\\\\t\\\\t(当 Class_Year = \\’PreSchool\\’ 然后 \\’PreSec\\’ \\\\t\\\\t\\\\t WHEN Class_Year = \\’Voc Yr1 \\’ 然后 \\’Voc_Yr1\\’ \\\\t\\\\t\\\\t WHEN Class_Year = \\’Voc Yr2\\’ 然后 \\’Voc_Yr2\\’ \\\\t\\\\t\\\\t WHEN Class_Year = \\’1\\’OR Class_Year = \\’2\\’OR Class_Year = \\’3\\’ ??\\\\t\\\\t\\\\t OR Class_Year = \\’4\\’OR Class_Year = \\’5\\’OR Class_Year = \\’6\\’ \\\\ t\\\\t\\\\t OR Class_Year = \\’7\\’OR Class_Year = \\’8\\’then \\’Primary\\’ \\\\t\\\\t\\\\t else \\’Secondary\\’ END) as SchType FROM [ FILNA].[dbo].[Student_Subject_Desc] 其中 SchType = \\’Primary\\’ group by Class_Year, Student_Subject_Type_Desc
- 我想在 where 子句中使用别名,但不能…请帮助
- 我已将我的答案更改为(希望)消除您第一条评论中的错误。我现在将陷入您的第二个评论问题。
- 另外,为什么要在 WHERE 子句中使用别名?
- 添加了解释。
来源:https://www.codenong.com/43712842/