在SQL查询中输出交叉引用矩阵结果
假设我有一个包含4条Id为1到4的记录的主表 然后,我有一个事务表,它维护一个记录到另一个记录的兼容性在SQL查询中输出交叉引用矩阵结果,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,假设我有一个包含4条Id为1到4的记录的主表 然后,我有一个事务表,它维护一个记录到另一个记录的兼容性 Record1 Record2 IsCompatible 1 2 True 1 3 True 4 1 False 2 3 False 4 2 True 3 4 True
Record1 Record2 IsCompatible
1 2 True
1 3 True
4 1 False
2 3 False
4 2 True
3 4 True
只有一条记录具有相同的Record1/Record2组合,但在这些记录中,确定给定记录是作为Record1还是Record2保存的逻辑取决于设置兼容性时源记录是什么。因此,任何记录在任何时候都可能是双向的
从这里,我想输出一个类似以下内容的记录集:
RecordID CompatabilityString
1 Null, True, True, False
2 True, Null, False, True
3 True, False, Null, True
4 False, True, True, Null
CompatibilityString以数字顺序返回每个项与所有其他项的兼容性,null表示与自身的关系
实现这一目标的最佳方式是什么
干杯首先,您应该将此表与其自身合并,以获得完整的矩阵,然后使用
MAX(CASE…)
旋转此表:
如果兼容性字符串只需要一列
:
SELECT X as RecordID,
ISNULL(MAX(CASE WHEN Y=1 THEN IsCompatible END),'NULL')+
','+
ISNULL(MAX(CASE WHEN Y=2 THEN IsCompatible END),'NULL')+
','+
ISNULL(MAX(CASE WHEN Y=3 THEN IsCompatible END),'NULL')+
','+
ISNULL(MAX(CASE WHEN Y=4 THEN IsCompatible END),'NULL')
as CompatabilityString
FROM
(
SELECT Record1 as X,Record2 as Y,IsCompatible FROM T
UNION ALL
SELECT Record2 as X,Record1 as Y,IsCompatible FROM T
) as T1
GROUP BY X
ORDER BY X
UPD:这里是关于可变维度的第二个查询。在本例中,XML路径的用于创建逗号分隔的列表:
;WITH T1 AS
(
SELECT Record1 as X,Record2 as Y,IsCompatible FROM T
UNION ALL
SELECT Record2 as X,Record1 as Y,IsCompatible FROM T
)
SELECT DISTINCT X,
STUFF(
(SELECT ',' + ISNULL(IsCompatible,'NULL')
FROM (SELECT DISTINCT X as Y FROM T1) as Tbase
LEFT JOIN T1 AS T2
ON TBase.Y=T2.Y AND T1.X = T2.X
ORDER BY TBase.Y
FOR XML PATH ('')
)
, 1, 1, '') AS COMPATABILITYSTRING
FROM T1
ORDER BY X
我喜欢将值实际输出为列而不是逗号分隔的字符串的选项,不过示例就是这样。实际上,可能有100多条记录需要交叉引用,因此需要动态构建列。这可能吗?第二个例子也是如此。如何做到这一点dynamically@StewartAlan:我已将查询添加到我的答案中,以创建变量维度的逗号分隔列表。如果您需要分离的列,那么这只能通过动态SQL完成。
;WITH T1 AS
(
SELECT Record1 as X,Record2 as Y,IsCompatible FROM T
UNION ALL
SELECT Record2 as X,Record1 as Y,IsCompatible FROM T
)
SELECT DISTINCT X,
STUFF(
(SELECT ',' + ISNULL(IsCompatible,'NULL')
FROM (SELECT DISTINCT X as Y FROM T1) as Tbase
LEFT JOIN T1 AS T2
ON TBase.Y=T2.Y AND T1.X = T2.X
ORDER BY TBase.Y
FOR XML PATH ('')
)
, 1, 1, '') AS COMPATABILITYSTRING
FROM T1
ORDER BY X