我有一个数据集,其中每个组都有一个标识符列,并且该组中每个实例都有一个值。我想根据特定条件将每个组的标识符改为行值,在这种情况下,我们假设以A
(每组一个实例)开头的行值。如何转换数据以创建这样的新标识符?
用于创建示例数据的代码
DECLARE @Test TABLE (
Val VARCHAR(3),
ID INT
)
INSERT INTO @Test VALUES ('ABC', 1);
INSERT INTO @Test VALUES ('DEF', 1);
INSERT INTO @Test VALUES ('GHI', 1);
INSERT INTO @Test VALUES ('JKL', 1);
INSERT INTO @Test VALUES ('MNO', 2);
INSERT INTO @Test VALUES ('ADE', 2);
INSERT INTO @Test VALUES ('PQR', 2);
我希望将每个组的A%
实例值作为一列来获得期望的结果。
ABC,1,ABC
DEF,1,ABC
GHI,1,ABC
JKL,1,ABC
MNO,2,ADE
ADE,2,ADE
PQR,2,ADE
答案 0 :(得分:3)
您可以使用窗口功能来代替2次扫描:
SELECT Val,
ID,
MIN(CASE WHEN Val LIKE 'A%' THEN Val END) OVER (PARTITION BY ID) AS Val2
FROM @Test;
如果在没有以NULL
开头的行时不希望使用A
,只需使用Val
而不是CASE
表达式。
答案 1 :(得分:1)
我认为您可以使用以下逻辑来实现
WITH CTE_1 AS (
SELECT ID,VAL FROM @Test WHERE Val like 'A%')
SELECT T1.*,CTE_1.Val FROM @Test T1
INNER JOIN CTE_1
ON T1.ID = CTE_1.ID
OR
SELECT Val, ID,
(SELECT TOP 1 Val FROM @Test T2 WHERE T2.Val like 'A%' AND T2.ID = T1.ID) as Val2
FROM @Test T1
OR
SELECT T1.*,CTE_1.Val
FROM @Test T1 INNER JOIN
(SELECT ID,VAL FROM @Test WHERE Val like 'A%') as CTE_1
ON T1.ID = CTE_1.ID
结果
答案 2 :(得分:0)
在选择语句中使用内部选择确实对性能不利。
改为使用左联接。
select t1.Val, t1.ID , t.Val as val2
from @Test t1
left join @Test t on t1.ID = t.ID and t.Val like 'A%'