根据2列值连接列

时间:2017-07-11 14:31:03

标签: sql sql-server grouping

我有一张表如下,让我们说TEMP

Desc_1 Desc_2 Score
a      b      10
a      c      10
x      y      10
x      z      10
a      d      9
a      e      9
a      f      8
f      g      8

我希望结果如下

a,b,c 10
x,y,z 10
a,d,e 9
a,f,g 8

所以第一条规则是组中的所有元素应该具有相同的分数。

分组的发生方式是

1)应该有一个直接的关系,a,b应该在表TEMP

2)如果TEMP中的条目为[(a,f)和(f,g)]或[(a,f)和,则可能存在a,g可能在同一组中的间接关系(G,F))]

P.S。很抱歉不断编辑。

4 个答案:

答案 0 :(得分:1)

尝试

 SELECT score, DESC_1 FROM yourTable 
 UNION 
 SELECT score, DESC_2 FROM yourTable 

然后根据此答案中显示的分数使用STUFFXML PATH

  

如何在SQL Server 2005中将多行组合成逗号分隔的列表?   https://stackoverflow.com/a/180375/3470178

答案 1 :(得分:1)

您可以使用以下内容和组:

;With cte as (
    Select Desc_1 as descr, score from #desc
    union 
    Select Desc_2 as descr, score from #desc
) select Score, 
    stuff((select distinct ',' + descr from cte where score = d.score for xml path('')),1,1,'')
    from cte d
    group by Score

输出如下:

+-------+-------+
| Descr | Score |
+-------+-------+
| a,f,g |     8 |
| a,d,e |     9 |
| a,b,c |    10 |
+-------+-------+

如果您使用的是SQL Server 2017或SQL Azure,则可以使用string_agg,如下所示

...cte
Select String_Agg(descr, ','), Score from cte
   group by Score

答案 2 :(得分:1)

STUFF和XML连接路径:

;with s as (Select distinct score from #scores),
fs as (
select s.score, d1.Desc_1 as col
from s
left join #scores d1 on d1.score=s.score
UNION
select s.score, d2.Desc_2 as col
from s
left join #scores d2 on d2.score=s.score)
SELECT  
       Columns = STUFF((SELECT ',' + col 
                          FROM fs sc
                          where sc.score=fs.score
                        FOR XML PATH('')),1,1,'')
        ,score
  FROM fs 
  group by score
  order by score desc

答案 3 :(得分:1)

这似乎正在返回所需的结果......

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    Desc_1 CHAR(1),
    Desc_2 CHAR(1),
    Score INT 
    );

INSERT #TestData (Desc_1, Desc_2, Score) VALUES
    ('a', 'b', 10),
    ('a', 'c', 10),
    ('x', 'y', 10),
    ('x', 'z', 10),
    ('a', 'd', 9),
    ('a', 'e', 9),
    ('a', 'f', 8),
    ('f', 'g', 8);

--SELECT * FROM #TestData td;

--============================================

WITH
    cte_UnPivValues AS (
        SELECT DISTINCT 
            td.Desc_1, 
            td.Score, 
            upv.UnPivValue
        FROM
            #TestData td
            CROSS APPLY ( VALUES (td.Desc_1), (td.Desc_2) ) upv (UnPivValue)
        )
SELECT 
    Descr = STUFF((
        SELECT 
            CONCAT(',', upv2.UnPivValue)
        FROM 
            cte_UnPivValues upv2
        WHERE 
            upv1.Desc_1 = upv2.Desc_1
            AND upv1.Score = upv2.Score
        ORDER BY
            upv2.UnPivValue
        FOR XML PATH ('')

    ), 1, 1, ''),
    upv1.Score
FROM
    cte_UnPivValues upv1
GROUP BY 
    upv1.Desc_1,
    upv1.Score
ORDER BY 
    upv1.Score DESC,
    Descr ASC;