我有一个视图,这是一个简单的案例陈述。
SELECT CAST(
CASE
WHEN [value] = 'Canadian' and fieldid = 78
THEN 5
WHEN [value] = 'US' and fieldid = 78
Then 3
WHEN [value] = 'UK' and fieldid = 78
Then 1
When [value] = 'Australia' and fieldid = 78
Then 1
When [value] = 'Israel' and fieldid = 78
Then 1
When [value] = 'Others' and fieldid = 78
Then 1
到目前为止,当列具有匹配值时,一切都可以正常,但是有时列可以保存由逗号分隔的随机多个值。我怎么能算出来? 这就是现在发生的事情。
+----+------------------+--------+
| ID | Value | Points |
+----+------------------+--------+
| 1 | Canadian | 5 |
| 2 | UK | 1 |
| 3 | Canadian,UK | 0 |
+----+----------+----------------+
预期结果
+----+------------------+--------+
| ID | Value | Points |
+----+------------------+--------+
| 1 | Canadian | 5 |
| 2 | UK | 1 |
| 3 | Canadian,UK | 6 |
+----+----------+----------------+
答案 0 :(得分:2)
从SQL Server 2017开始,您可以使用:
SELECT DISTINCT t.ID, t.[value],
SUM(CASE
WHEN s.[value] = 'Canadian' and fieldid = 78
THEN 5
WHEN s.[value] = 'US' and fieldid = 78
Then 3
WHEN s.[value] = 'UK' and fieldid = 78
Then 1
When s.[value] = 'Australia' and fieldid = 78
Then 1
When s.[value] = 'Israel' and fieldid = 78
Then 1
When s.[value] = 'Others' and fieldid = 78
Then 1
END) OVER(PARTITION BY ID) AS Points
FROM tab t
CROSS APPLY STRING_SPLIT(t.[value], ',') s
ORDER BY t.id;
<强> DBFiddle Demo 强>
在单列中存储多个值会违反第一范式,应该避免使用。
可以简化为:
SELECT DISTINCT t.ID, t.[value],
SUM(CASE
WHEN s.[value] = 'Canadian' and fieldid = 78
THEN 5
WHEN s.[value] = 'US' and fieldid = 78
Then 3
WHEN s.[value] IN ('UK', 'Australia' , 'Israel', 'Others')
and fieldid = 78
Then 1
END) OVER(PARTITION BY ID) AS Points
FROM tab t
CROSS APPLY STRING_SPLIT(t.[value], ',') s
ORDER BY t.id;
答案 1 :(得分:2)
您只需使用CASE
和LIKE
:
SELECT ((CASE WHEN ',' + [value] + ',' LIKE '%,Canadian,%' and fieldid = 78
THEN 5 ELSE 0
END) +
(CASE WHEN ',' + [value] + ',' LIKE '%,US,%' and fieldid = 78
THEN 3 ELSE 0
END) +
(CASE WHEN ',' + [value] + ',' LIKE '%,UK,%' and fieldid = 78
THEN 1 ELSE 0
END) +
(CASE WHEN ',' + [value] + ',' LIKE '%,Australia,%' and fieldid = 78
THEN 1 ELSE 0
END) +
(CASE WHEN ',' + [value] + ',' LIKE '%,Israel,%' and fieldid = 78
THEN 1 ELSE 0
END) +
(CASE WHEN ',' + [value] + ',' LIKE '%,Others,%' and fieldid = 78
THEN 1 ELSE 0
END)
) as val
尽管如此,强烈地强烈反对强烈建议您不要在单个列中存储多个值。 SQL旨在在列中存储单个值(至少对于标量列类型,字符串是标量类型)。
您应该有一个单独的表,它是一个联结/关联表,每个实体和国家/地区都有一行。
编辑:如果您使用的是SQL Server 2017或者有分割字符串功能,我会建议您这样做:
SELECT t.ID, t.[value], COALESCE(s.points, 0) as points
FROM tab t OUTER APPLY
(SELECT SUM(CASE WHEN s.[value] = 'Canadian' THEN 5
WHEN s.[value] = 'US' THEN 3
WHEN s.[value] IN ('UK', 'Australia' , 'Israel', 'Others') THEN 1
END) AS Points
FROM STRING_SPLIT(t.[value], ',') s
WHERE t.fieldid = 78
) s
ORDER BY t.id;