【发布时间】:2016-06-15 17:51:58
【问题描述】:
在下面的端口中带有 case 语句的查询中,我试图弄清楚当 SegmentType 不匹配时如何不返回空值。
QRSubscriberTag、MLKSubscriberTag、QTMSubscriber Tag,实际上是一个Tags的表,由它们的SegID和与SegID关联的segmentType唯一标识。我将外部应用与调用 FOR XML PATH('') 的子查询一起使用,以将与特定标签相关的标签连接在一起。
这种方法的缺陷是当标签不是例如 QRSubscriberTag 时,会在 QRSubscriberTag 列中创建一个空记录。
QRSubscriberTag|QR01|MLKSubscriberTag|MLK01|QTMSubscriberTag|QTM01|QTM02
NULL |NULL|NULL |{Data}|null |FH |45
TKP ;OCP ;OCR ;|R |NULL |null |null |null |null
我希望看到的是 1 行中的所有数据
QRSubscriberTag|QR01|MLKSubscriberTag|MLK01|QTMSubscriberTag|QTM01|QTM02
TKP ;OCP ;OCR ;|R |NULL |{Data}|null |FH |45
下面是我的代码
SET NOCOUNT ON
USE [Apps]
SELECT [BusRuleEnforceID], [FormatType], [Format],
[tag], [TagValue], Operator,
[QRSubscriberTag],[QR01],
[MLKSubscriberTag],[MLK01],
[QTMSubscriberTag],[QTM01],[QTM02]
FROM
(
SELECT
DISTINCT main.BusRuleEnforceID,
main.FormatType,
main.Format,
main.tag,
main.TagValue,
main.Operator,
CASE
WHEN seg.SegmentType = 'QR' THEN LEFT(SegsubscriberTags.list, LEN(SegsubscriberTags.list))
END AS [QRSubscriberTag],
CASE
WHEN seg.SegmentType = 'MLK' THEN LEFT(SegsubscriberTags.list, LEN(SegsubscriberTags.list)-1)
END AS [MLKSubscriberTag],
CASE
WHEN seg.SegmentType = 'QTM' THEN LEFT(SegsubscriberTags.list, LEN(SegsubscriberTags.list)-1)
END AS [QTMSubscriberTag],
c.ItemName as [SegmentId],
Case
WHEN c.ItemValue is not null and len(rtrim(c.ItemValue)) > 0 THEN c.ItemValue
ELSE LEFT(TagOptions.list, LEN(TagOptions.list)-1)
END as [Tags]
FROM
BMT_BusRulemaineria main
LEFT OUTER JOIN
BMT_BusRuleServiceType st
ON st.MappingmaineriaID = main.BusRuleEnforceID
LEFT OUTER JOIN
BMT_BusRuleSegment seg
ON seg.BusRuleEnforceID = main.BusRuleEnforceID
LEFT OUTER JOIN
BMT_BusRuleItem c
ON c.BusRuleEnforceSegID = seg.BusRuleEnforceSegID
LEFT OUTER JOIN
BMT_BusRuleItemOption co
ON c.BusRuleItemId = co.BusRuleItemId
OUTER APPLY
(
SELECT
IsNull(co2.Tag, '{Unknown}') + ISNULL('=' + co2.TagValue, '') + ':' + IsNull(co2.ItemValue, '')+ ';' AS [text()]
FROM
BMT_BusRuleItemOption co2
WHERE
co.BusRuleItemId = co2.BusRuleItemId
ORDER BY
co2.BusRuleItemId
FOR XML PATH('')
) TagOptions (list)
OUTER APPLY
(
SELECT
IsNull(porttag.Tag, '{Unknown}') + ' ' + ISNULL(porttag.Operator, '') + ' ' + IsNull(porttag.TagValue, '') + ';' AS [text()]
FROM
BMT_BusRuleSegmentTag porttag
WHERE
seg.BusRuleEnforceSegID = porttag.BusRuleEnforceSegID
ORDER BY
porttag.BusRuleEnforceSegID
FOR XML PATH('')
) SegsubscriberTags (list)
WHERE main.BusRuleEnforceID = 632563
AND main.TagTypeId = 1
) AS QRSourceTable
PIVOT
(
max([Tags])
FOR [SegmentId] IN ([QR01], [MLK01], [QTM01], [QTM02])
) AS QRPivotTable
ORDER BY
[TagTypeId], [BusRuleEnforceID]
编辑:完整结果集 注意:QRSubscriber、MLKSubscriber 和 QTMSubscriber 标签都有唯一的 SegID。
<table><tbody><tr><th>FormatType</th><th>Format</th><th>Version</th><th>AmtCode</th><th>Date</th><th>LocationIdentifier</th><th>TagType</th><th>tag</th><th>TagValue</th><th>Operator</th><th>InfoCode</th><th>QRSubscriberTag</th><th>QR01</th><th>QR02</th><th>QR03</th><th>QR04</th><th>QR05</th><th>QR06</th><th>QR07</th><th>MLKSubscriberTag</th><th>MLK01</th><th>QTMSubscriberTag</th><th>QTM01</th><th>QTM02</th></tr><tr><td>DN</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>TIR</td><td>RPSAMN</td><td>NULL</td><td>exists</td><td>78</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>{Data}</td><td>NULL</td><td>TRH</td><td>675</td></tr><tr><td>DN</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>TIR</td><td>RPSAMN</td><td>NULL</td><td>exists</td><td>78</td><td>TKRARAP not exists TKRALAP not exists TKRADAP not exists </td><td>J</td><td>SKU</td><td>34</td><td>NULL</td><td>NULL</td><td>SILMULTU:2;SILMHLTU:67</td><td>TOPALD:{Data};QORITK{Data}</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td></tr></tbody></table>
【问题讨论】:
-
嗯,不要在你的case语句中使用NULL?您可以使用空白字符串,例如 '' 或您选择的任何其他标记值。
-
忘记删除它们。在这种情况下,else null 不做任何事情。例如,如果我这样做:
CASE WHEN port.SegmentType = 'QR' THEN LEFT(SegDependantTags.list, LEN(SegDependantTags.list)) END AS [QRSubscriberTag]结果将是相同的。 Case 语句在 Segment 不是 QR 的情况下创建空值。 -
确保发布您实际使用的代码。这不会通过语法检查。您正在引用一个名为“端口”的表或别名,该表或别名在您的 from 子句中的任何位置都不存在。
-
现在您添加的输出与您的代码将生成的相同字段不匹配。
标签: sql-server case dynamic-columns outer-apply