转置和识别带有标志的单元格
Transposing and identifying the cell with a flag
我有一个包含三列的 table。值列始终为 NULL
。我知道如何将行转置为列,但我还想用 'X'.
标识单元格
Table
EditorTypeSymbolicName ClaimFieldSymbolicName Value
01 AA NULL
01 BB NULL
01 CC NULL
02 BB NULL
02 CC NULL
03 AA NULL
这是我的代码
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName)
FROM #TempEditElements
ORDER BY 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + '
FROM
(
select EditorTypeSymbolicName, ClaimFieldSymbolicName, Value
from #TempEditElements
) s
PIVOT
(
MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ')
) p
order by EditorTypeSymbolicName'
EXECUTE(@sql)
我的代码转置了它,但我不知道如何用 'X' 标记它们。我希望输出如下:
EditorTypeSymbolicName AA BB CC
01 X X X
02 NULL X X
03 X NULL NULL
当前输出如下所示
EditorTypeSymbolicName AA BB CC
01 NULL NULL NULL
02 NULL NULL NULL
03 NULL NULL NULL
静态解决方案
select *
from (select 'X' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t
pivot (max(x) for ClaimFieldSymbolicName in ([AA],[BB],[CC])) t
order by EditorTypeSymbolicName
;
动态解决方案
declare @columns nvarchar(max) = ''
,@stmt nvarchar(max)
;
----------
select @columns += case @columns when '' then '' else ',' end + QUOTENAME (ClaimFieldSymbolicName,'[')
from t
group by ClaimFieldSymbolicName
order by ClaimFieldSymbolicName
;
----------
set @stmt =
'
select *
from (select ''X'' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t
pivot (max(x) for ClaimFieldSymbolicName in ('+ @columns + ')) t
order by EditorTypeSymbolicName
'
;
----------
exec (@stmt)
半静态解决方案
select (select top 0 EditorTypeSymbolicName from t) as EditorTypeSymbolicName,t.*
from (select distinct ClaimFieldSymbolicName,dense_rank () over (order by ClaimFieldSymbolicName) as dr from t) t
pivot (max(ClaimFieldSymbolicName) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t
union all
select *
from (select 'X' as x,EditorTypeSymbolicName,dense_rank () over (order by ClaimFieldSymbolicName) as dr from t) t
pivot (max(x) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t
order by 1
;
╔════════════════════════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╗
║ EditorTypeSymbolicName ║ 1 ║ 2 ║ 3 ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║ 10 ║
╠════════════════════════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╣
║ NULL ║ AA ║ BB ║ CC ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 01 ║ X ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 02 ║ NULL ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 03 ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
╚════════════════════════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╝
这是一种方法。在动态查询中,
- 为
EditorTypeSymbolicName X ClaimFieldSymbolicName
(CROSS JOIN
部分)创建了一个 "matrix"
- 然后链接到原始 table 以查找每个组合是否存在一行(
LEFT JOIN
部分)
- 如果存在一行,
Value
将替换为您需要的 X
(Value=CASE ...
部分)
CREATE TABLE #TempEditElements(EditorTypeSymbolicName VARCHAR(128),ClaimFieldSymbolicName VARCHAR(128),Value VARCHAR(128));
INSERT INTO #TempEditElements(EditorTypeSymbolicName,ClaimFieldSymbolicName,Value)
VALUES ('01','AA',NULL),('01','BB',NULL),('01','CC',NULL),('02','BB',NULL),('02','CC',NULL),('03','AA',NULL);
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName)
FROM #TempEditElements
ORDER BY 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + '
FROM
(
SELECT
ets.EditorTypeSymbolicName,
cfs.ClaimFieldSymbolicName,
Value=CASE WHEN tee.EditorTypeSymbolicName IS NULL AND tee.ClaimFieldSymbolicName IS NULL THEN NULL ELSE ''X'' END
FROM
(SELECT DISTINCT EditorTypeSymbolicName FROM #TempEditElements) AS ets
CROSS JOIN (SELECT DISTINCT ClaimFieldSymbolicName FROM #TempEditElements) AS cfs
LEFT JOIN #TempEditElements AS tee ON
tee.EditorTypeSymbolicName=ets.EditorTypeSymbolicName AND
tee.ClaimFieldSymbolicName=cfs.ClaimFieldSymbolicName
) s
PIVOT
(
MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ')
) p
order by EditorTypeSymbolicName'
EXECUTE (@sql);
DROP TABLE #TempEditElements;
结果是:
╔════════════════════════╦══════╦══════╦══════╗
║ EditorTypeSymbolicName ║ AA ║ BB ║ CC ║
╠════════════════════════╬══════╬══════╬══════╣
║ 01 ║ X ║ X ║ X ║
║ 02 ║ NULL ║ X ║ X ║
║ 03 ║ X ║ NULL ║ NULL ║
╚════════════════════════╩══════╩══════╩══════╝
我有一个包含三列的 table。值列始终为 NULL
。我知道如何将行转置为列,但我还想用 'X'.
Table
EditorTypeSymbolicName ClaimFieldSymbolicName Value
01 AA NULL
01 BB NULL
01 CC NULL
02 BB NULL
02 CC NULL
03 AA NULL
这是我的代码
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName)
FROM #TempEditElements
ORDER BY 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + '
FROM
(
select EditorTypeSymbolicName, ClaimFieldSymbolicName, Value
from #TempEditElements
) s
PIVOT
(
MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ')
) p
order by EditorTypeSymbolicName'
EXECUTE(@sql)
我的代码转置了它,但我不知道如何用 'X' 标记它们。我希望输出如下:
EditorTypeSymbolicName AA BB CC
01 X X X
02 NULL X X
03 X NULL NULL
当前输出如下所示
EditorTypeSymbolicName AA BB CC
01 NULL NULL NULL
02 NULL NULL NULL
03 NULL NULL NULL
静态解决方案
select *
from (select 'X' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t
pivot (max(x) for ClaimFieldSymbolicName in ([AA],[BB],[CC])) t
order by EditorTypeSymbolicName
;
动态解决方案
declare @columns nvarchar(max) = ''
,@stmt nvarchar(max)
;
----------
select @columns += case @columns when '' then '' else ',' end + QUOTENAME (ClaimFieldSymbolicName,'[')
from t
group by ClaimFieldSymbolicName
order by ClaimFieldSymbolicName
;
----------
set @stmt =
'
select *
from (select ''X'' as x,EditorTypeSymbolicName,ClaimFieldSymbolicName from t) t
pivot (max(x) for ClaimFieldSymbolicName in ('+ @columns + ')) t
order by EditorTypeSymbolicName
'
;
----------
exec (@stmt)
半静态解决方案
select (select top 0 EditorTypeSymbolicName from t) as EditorTypeSymbolicName,t.*
from (select distinct ClaimFieldSymbolicName,dense_rank () over (order by ClaimFieldSymbolicName) as dr from t) t
pivot (max(ClaimFieldSymbolicName) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t
union all
select *
from (select 'X' as x,EditorTypeSymbolicName,dense_rank () over (order by ClaimFieldSymbolicName) as dr from t) t
pivot (max(x) for dr in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10])) t
order by 1
;
╔════════════════════════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╗
║ EditorTypeSymbolicName ║ 1 ║ 2 ║ 3 ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║ 10 ║
╠════════════════════════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╬══════╣
║ NULL ║ AA ║ BB ║ CC ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 01 ║ X ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 02 ║ NULL ║ X ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
║ 03 ║ X ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║ NULL ║
╚════════════════════════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╝
这是一种方法。在动态查询中,
- 为
EditorTypeSymbolicName X ClaimFieldSymbolicName
(CROSS JOIN
部分)创建了一个 "matrix" - 然后链接到原始 table 以查找每个组合是否存在一行(
LEFT JOIN
部分) - 如果存在一行,
Value
将替换为您需要的X
(Value=CASE ...
部分)
CREATE TABLE #TempEditElements(EditorTypeSymbolicName VARCHAR(128),ClaimFieldSymbolicName VARCHAR(128),Value VARCHAR(128));
INSERT INTO #TempEditElements(EditorTypeSymbolicName,ClaimFieldSymbolicName,Value)
VALUES ('01','AA',NULL),('01','BB',NULL),('01','CC',NULL),('02','BB',NULL),('02','CC',NULL),('03','AA',NULL);
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(ClaimFieldSymbolicName)
FROM #TempEditElements
ORDER BY 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @sql = 'SELECT EditorTypeSymbolicName, ' + @cols + '
FROM
(
SELECT
ets.EditorTypeSymbolicName,
cfs.ClaimFieldSymbolicName,
Value=CASE WHEN tee.EditorTypeSymbolicName IS NULL AND tee.ClaimFieldSymbolicName IS NULL THEN NULL ELSE ''X'' END
FROM
(SELECT DISTINCT EditorTypeSymbolicName FROM #TempEditElements) AS ets
CROSS JOIN (SELECT DISTINCT ClaimFieldSymbolicName FROM #TempEditElements) AS cfs
LEFT JOIN #TempEditElements AS tee ON
tee.EditorTypeSymbolicName=ets.EditorTypeSymbolicName AND
tee.ClaimFieldSymbolicName=cfs.ClaimFieldSymbolicName
) s
PIVOT
(
MAX(Value) FOR ClaimFieldSymbolicName IN (' + @cols + ')
) p
order by EditorTypeSymbolicName'
EXECUTE (@sql);
DROP TABLE #TempEditElements;
结果是:
╔════════════════════════╦══════╦══════╦══════╗
║ EditorTypeSymbolicName ║ AA ║ BB ║ CC ║
╠════════════════════════╬══════╬══════╬══════╣
║ 01 ║ X ║ X ║ X ║
║ 02 ║ NULL ║ X ║ X ║
║ 03 ║ X ║ NULL ║ NULL ║
╚════════════════════════╩══════╩══════╩══════╝