代码之家  ›  专栏  ›  技术社区  ›  littlegreen

为数据组选择distinct

  •  5
  • littlegreen  · 技术社区  · 15 年前

    我有下表:

    ID  Data
    1   A
    2   A
    2   B
    3   A
    3   B
    4   C
    5   D 
    6   A
    6   B
    

    换句话说,我有每个ID的数据组。您会注意到数据组(A,B)出现了多次。我需要一个可以识别不同数据组并对其编号的查询,例如:

    DataID     Data
    101        A
    102        A
    102        B
    103        C
    104        D
    

    因此,dataid 102将类似于数据(A、B),dataid 103将类似于数据(C)等,以便能够以这种形式重写原始表:

    ID   DataID
    1    101
    2    102
    3    102
    4    103
    5    104
    6    102
    

    我该怎么做?


    ps.生成第一个表的代码:

    CREATE TABLE #t1 (id INT, data VARCHAR(10))
    INSERT INTO #t1
    SELECT 1, 'A'
    UNION ALL SELECT 2, 'A'
    UNION ALL SELECT 2, 'B'
    UNION ALL SELECT 3, 'A'
    UNION ALL SELECT 3, 'B'
    UNION ALL SELECT 4, 'C'
    UNION ALL SELECT 5, 'D'
    UNION ALL SELECT 6, 'A'
    UNION ALL SELECT 6, 'B'
    
    4 回复  |  直到 15 年前
        1
  •  3
  •   luckyluke    15 年前

    在我看来,您必须创建一个连接数据的自定义聚合(对于字符串,出于性能原因,建议使用clr方法)。 然后我将按ID分组并选择不同于分组的,添加一个row_number()函数或添加一个密集的_rank()您的选择。不管怎样,应该是这样的

    with groupings as (
    select concat(data) groups
    from Table1
    group by ID
    )
    select groups, rownumber() over () from groupings
    
        2
  •  2
  •   Jagmag    15 年前

    下面的查询用例将给出下面显示的结果。

    从那时起,获取不同的数据组并进一步进行不应该是真正的问题。

    SELECT     
        id, 
         MAX(CASE data WHEN 'A' THEN data ELSE '' END) + 
         MAX(CASE data WHEN 'B' THEN data ELSE '' END) + 
         MAX(CASE data WHEN 'C' THEN data ELSE '' END) + 
         MAX(CASE data WHEN 'D' THEN data ELSE '' END) AS DataGroups
    FROM  t1
    GROUP BY id
    
    ID  DataGroups
    1   A
    2   AB
    3   AB
    4   C
    5   D
    6   AB
    

    然而,这种逻辑只有在“数据”值是固定的并且在手之前就已经知道的情况下才能工作。

    在你的情况下,你确实这么说。但是,考虑到你也说他们是1000人,坦率地说,这肯定是一个看起来很荒谬的问题。

    坦率地说,Luckyluke上面的建议将是更通用的方法,并且可能是更明智的方法来实现解决方案,尽管在您的案例中。

        3
  •  0
  •   Damien_The_Unbeliever    15 年前

    从您的示例数据(添加了缺少的2个“a”元组后,下面给出了重新编号(和唯一化)的数据:

    with NonDups as (
    select t1.id
    from #t1 t1 left join #t1 t2
    on t1.id > t2.id and t1.data = t2.data
    group by t1.id
    having COUNT(t1.data) > COUNT(t2.data)
    ), DataAddedBack as (
        select ID,data
        from #t1 where id in (select id from NonDups)
    ), Renumbered as (
        select DENSE_RANK() OVER (ORDER BY id) as ID,Data from DataAddedBack
    )
    select * from Renumbered
    

    给:

    1          A
    2          A
    2          B
    3          C
    4          D
    

    然后,我认为,将输出中的行与原始表中的行进行匹配是关系除法的问题。

        4
  •  0
  •   littlegreen    15 年前

    只是为了分享我目前使用的肮脏解决方案:

    SELECT DISTINCT t1.id, D.data
    FROM #t1 t1
    CROSS APPLY ( 
        SELECT CAST(Data AS VARCHAR) + ','
        FROM #t1 t2
        WHERE t2.id = t1.id
        ORDER BY Data ASC
        FOR XML PATH('') )  
    D ( Data )
    

    然后模拟Luckyluke的解决方案。