根据记录获取列
Getting a column based on a record
在输入 table 中,值每周都在变化。因此,下周 E 列将有 A 而不是 F,那时我想要 E 字段。
因此,必须选择具有 A 的字段,但具有 A 的字段应该是 table 中最后一个具有 A 作为记录的字段。
输入Table:
A | B | C | D | E
A A A A F
12 32 43 23 2
输出:
D
A
23
我知道您的数据由于某种原因未规范化,如果您需要逻辑来获取结果,您可以使用此代码:
DECLARE @table TABLE (A varchar(3), B varchar(3),C varchar(3), D varchar(3), E varchar(3))
;WITH cte
AS (SELECT ColumnName
,ColumnValue
,Row_number()
OVER(
partition BY ColumnName
ORDER BY Rn) ResultOrder
FROM (SELECT Row_number() OVER (ORDER BY (SELECT NULL))Rn,a ,b ,c ,d ,e FROM @table) p
UNPIVOT ( ColumnValue
FOR ColumnName IN( a ,b ,c ,d ,e)) AS unpvt),
cte1
AS (SELECT Ntile(5)
OVER(
ORDER BY ColumnName) ColumnId
,*
FROM cte),
cte2
AS (SELECT DISTINCT Isnull(NULLIF(ColumnId - 1, 0), 5) ColumnId
,ColumnName
FROM cte1
WHERE ColumnValue = 'F')
SELECT result
FROM (SELECT CASE ColumnId
WHEN 1 THEN 'A'
WHEN 2 THEN 'B'
WHEN 3 THEN 'C'
WHEN 4 THEN 'D'
WHEN 5 THEN 'E'
END Result
,0 ResultOrder
FROM cte2
UNION
SELECT ColumnValue
,resultorder
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)) AS R
ORDER BY resultorder
的结果
insert @table VALUES
('A','A','A','A','F')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
A A A A F
12 32 43 23 2
result
------
D
23
A
的结果
insert @table VALUES
('F','A','A','A','A')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
F A A A A
12 32 43 23 2
result
------
E
A
2
解释:
- CTE table 执行 Unpivot table 并创建行号以对列名和值进行排序
- CT1 table 根据列名创建一个组,使用 NTILE 创建 5 个组
- CTE2 table 获取值等于 F 的前一列
- Select将ColumnId转为ColumnName比较复杂,如果不需要,
你可以使用
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
Result
------
A
23
(2 row(s) affected)
或
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
AND a.ResultOrder = 2
Result
------
23
(1 row(s) affected)
在输入 table 中,值每周都在变化。因此,下周 E 列将有 A 而不是 F,那时我想要 E 字段。
因此,必须选择具有 A 的字段,但具有 A 的字段应该是 table 中最后一个具有 A 作为记录的字段。
输入Table:
A | B | C | D | E
A A A A F
12 32 43 23 2
输出:
D
A
23
我知道您的数据由于某种原因未规范化,如果您需要逻辑来获取结果,您可以使用此代码:
DECLARE @table TABLE (A varchar(3), B varchar(3),C varchar(3), D varchar(3), E varchar(3))
;WITH cte
AS (SELECT ColumnName
,ColumnValue
,Row_number()
OVER(
partition BY ColumnName
ORDER BY Rn) ResultOrder
FROM (SELECT Row_number() OVER (ORDER BY (SELECT NULL))Rn,a ,b ,c ,d ,e FROM @table) p
UNPIVOT ( ColumnValue
FOR ColumnName IN( a ,b ,c ,d ,e)) AS unpvt),
cte1
AS (SELECT Ntile(5)
OVER(
ORDER BY ColumnName) ColumnId
,*
FROM cte),
cte2
AS (SELECT DISTINCT Isnull(NULLIF(ColumnId - 1, 0), 5) ColumnId
,ColumnName
FROM cte1
WHERE ColumnValue = 'F')
SELECT result
FROM (SELECT CASE ColumnId
WHEN 1 THEN 'A'
WHEN 2 THEN 'B'
WHEN 3 THEN 'C'
WHEN 4 THEN 'D'
WHEN 5 THEN 'E'
END Result
,0 ResultOrder
FROM cte2
UNION
SELECT ColumnValue
,resultorder
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)) AS R
ORDER BY resultorder
的结果
insert @table VALUES
('A','A','A','A','F')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
A A A A F
12 32 43 23 2
result
------
D
23
A
的结果
insert @table VALUES
('F','A','A','A','A')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
F A A A A
12 32 43 23 2
result
------
E
A
2
解释:
- CTE table 执行 Unpivot table 并创建行号以对列名和值进行排序
- CT1 table 根据列名创建一个组,使用 NTILE 创建 5 个组
- CTE2 table 获取值等于 F 的前一列
- Select将ColumnId转为ColumnName比较复杂,如果不需要,
你可以使用
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
Result
------
A
23
(2 row(s) affected)
或
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
AND a.ResultOrder = 2
Result
------
23
(1 row(s) affected)