英文:
Match and coalesce multiple abbreviated possibilities
问题
SELECT ProjectID,
CONCAT_WS(', ',
CASE WHEN CHARINDEX('00', SpecialConditions) > 0 THEN 'No Fruits' ELSE NULL END,
CASE WHEN CHARINDEX('CB', SpecialConditions) > 0 THEN 'Cranberry' ELSE NULL END,
CASE WHEN CHARINDEX('K', SpecialConditions) > 0 THEN 'Kiwi' ELSE NULL END,
CASE WHEN CHARINDEX('SP', SpecialConditions) > 0 THEN 'Sugar Plum' ELSE NULL END,
CASE WHEN CHARINDEX('WM', SpecialConditions) > 0 THEN 'Watermelon' ELSE NULL END
) AS SpecialConditions
FROM Projects;
英文:
I have a table of project ID data and another of abbreviated circumstances related to the project. I would like to have the query output all the abbreviated options in a coalesced and descriptive format.
ProjectID is int
SpecialConditions is varchar
Query:
| ProjectID | SpecialConditions |
| -------- | ----------------- |
| 2023-0001 | 00 |
| 2023-0002 | CBSP |
| 2023-0003 | KCB |
| 2023-0004 | |
| 2023-0005 | K |
| 2023-0006 | WMCBSP |
List of abbreviated details:
00 = No Fruits
CB = Cranberry
K = Kiwi
SP = Sugar Plum
WM = Watermelon
Desired output:
| ProjectID | SpecialConditions |
| -------- | --------------------------------- |
| 2023-0001 | No Fruits |
| 2023-0002 | Cranberry, Sugar Plum |
| 2023-0003 | Kiwi, Cranberry |
| 2023-0004 | |
| 2023-0005 | Kiwi |
| 2023-0006 | Watermelon, Cranberry, Sugar Plum |
Previously I was using CASE, then I started realizing multiple conditions exist in different order which requires me to rewrite the query.
SELECT CASE When SpecialConditions = '00' then 'No Fruits'
When SpecialConditions = 'CB' then 'Cranberry'
When SpecialConditions = 'K' then 'Kiwi'
When SpecialConditions = 'SP' then 'Sugar Plum'
When SpecialConditions = 'WM' then 'Watermelon'
When SpecialConditions = 'SPWM' then 'Sugar Plum, Watermelon'
When SpecialConditions = 'WMSP' then 'Sugar Plum, Watermelon'
else (coalesce(SpecialConditions, '') END as 'Fruits'`
From Projects
Looking for any feedback on how I can write this query
答案1
得分: 3
如果您定义并填充了一个查找表,将代码映射到描述,您可以使用LIKE
运算符或CHARINDEX()
函数匹配查找表条目。然后可以使用STRING_AGG()
函数来组合结果。
SELECT P.ProjectID, P.SpecialConditions, A.Fruits
FROM Projects P
CROSS APPLY (
SELECT COALESCE(
STRING_AGG(FL.Description, ', ') WITHIN GROUP(ORDER BY M.MatchPos)
, P.SpecialConditions
, '') AS Fruits
FROM FruitLookup FL
CROSS APPLY (SELECT CHARINDEX(FL.Code, P.SpecialConditions) AS MatchPos) M
WHERE M.MatchPos > 0
) A
对于SQL Server 2016及更早版本,可以在STRING_AGG()
函数的位置使用旧的FOR XML
技巧。
SELECT P.ProjectID, P.SpecialConditions, A.Fruits
FROM Projects P
CROSS APPLY (
SELECT COALESCE(
STUFF((
SELECT ', ' + FL.Description
FROM FruitLookup FL
CROSS APPLY (SELECT CHARINDEX(FL.Code, P.SpecialConditions) AS MatchPos) M
WHERE M.MatchPos > 0
ORDER BY M.MatchPos
FOR XML PATH(''), TYPE
).value('.', 'varchar(max)'), 1, 2, '')
, P.SpecialConditions
, '') AS Fruits
) A
上述代码将按照它们在原始字符串中出现的顺序(在上述代码中的MatchPos)对映射的名称进行排序。
请注意,匹配逻辑不能防止由包含字符序列的相邻代码引起的意外匹配。您需要想出一种处理这些情况的策略。
示例结果:
ProjectID | SpecialConditions | Fruits |
---|---|---|
2023-0001 | 00 | No Fruits |
2023-0002 | CBSP | Cranberry, Sugar Plum |
2023-0003 | KCB | Kiwi, Cranberry |
2023-0004 | ||
2023-0005 | K | Kiwi |
2023-0006 | WMCBSP | Watermelon, Cranberry, Sugar Plum |
2023-0007 | SPCBWM | Sugar Plum, Cranberry, Watermelon |
参见 这个 db<>fiddle,其中包含上述代码的工作示例。
英文:
If you define and populate a lookup table that maps codes to descriptions, you can match lookup table entries using a LIKE
operator or CHARINDEX()
function. The STRING_AGG()
function can then be used to combine the results.
SELECT P.ProjectID, P.SpecialConditions, A.Fruits
FROM Projects P
CROSS APPLY (
SELECT COALESCE(
STRING_AGG(FL.Description, ', ') WITHIN GROUP(ORDER BY M.MatchPos)
, P.SpecialConditions
, '') AS Fruits
FROM FruitLookup FL
CROSS APPLY (SELECT CHARINDEX(FL.Code, P.SpecialConditions) AS MatchPos) M
WHERE M.MatchPos > 0
) A
For SQL Server 2016 and earlier, the old FOR XML
hack can be used in place of the STRING_AGG()
function.
SELECT P.ProjectID, P.SpecialConditions, A.Fruits
FROM Projects P
CROSS APPLY (
SELECT COALESCE(
STUFF((
SELECT ', ' + FL.Description
FROM FruitLookup FL
CROSS APPLY (SELECT CHARINDEX(FL.Code, P.SpecialConditions) AS MatchPos) M
WHERE M.MatchPos > 0
ORDER BY M.MatchPos
FOR XML PATH(''), TYPE
).value('.', 'varchar(max)'), 1, 2, '')
, P.SpecialConditions
, '') AS Fruits
) A
The above will order the mapped names in the same order as they appear in the original string (MatchPos in the above code).
Note that the matching logic does not protect against accidental matches caused by adjacent codes that contain character sequences that happen to match other codes. You will need to figure out a strategy to handle those cases.
Sample results:
ProjectID | SpecialConditions | Fruits |
---|---|---|
2023-0001 | 00 | No Fruits |
2023-0002 | CBSP | Cranberry, Sugar Plum |
2023-0003 | KCB | Kiwi, Cranberry |
2023-0004 | ||
2023-0005 | K | Kiwi |
2023-0006 | WMCBSP | Watermelon, Cranberry, Sugar Plum |
2023-0007 | SPCBWM | Sugar Plum, Cranberry, Watermelon |
See this db<>fiddle for a working example that includes both versions of the above code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论