使用符合组值的条件作为新的组标识符

时间:2019-02-21 21:48:38

标签: sql sql-server tsql

我有一个数据集,其中每个组都有一个标识符列,并且该组中每个实例都有一个值。我想根据特定条件将每个组的标识符改为行值,在这种情况下,我们假设以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

3 个答案:

答案 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

结果

enter image description here

答案 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%'