为2列上具有相同值的唯一ID选择并创建新ID

时间:2015-08-21 09:18:30

标签: sql sql-server select sql-server-2012

我的表

 ID  Name    Addr   tDate
-------------------------------
| 1 | Aa  |  street |  20151231
| 2 | Aa  |  street |  20130202
| 2 | Aa  |  street |  20120101
| 3 | Aa  |  way    |  20150821
| 4 | Bb  |  street |  20150821 
| 7 | Xb  |  street |  20150821 
| 5 | Cc  |  way    |  20150821
| 5 | Cc  |  way    |  20150821
| 6 | Cc  |  no way |  20150821

结果01

 ID  Name    Addr   | tDate
-------------------------------
| 1 | Aa  |  street |  20151231
| 2 | Aa  |  street |  20130202
| 2 | Aa  |  street |  20120101

要创建新的nID 如果Name和Addr相同,则应按照OR合并进行复制,并选择ID最新tDate

结果02

 ID  Name    Addr      tDate      nID
------------------------------------
| 1 | Aa  |  street |  20151231 | 1
| 2 | Aa  |  street |  20120101 | 1    <-- nID != ID
| 2 | Aa  |  street |  20130202 | 1    <-- nID != ID
| 3 | Aa  |  way    |  20150821 | 3
| 4 | Bb  |  street |  20150821 | 4 
| 7 | Xb  |  street |  20150821 | 7 
| 5 | Cc  |  way    |  20150821 | 5
| 5 | Cc  |  way    |  20150821 | 5
| 6 | Cc  |  no way |  20150821 | 6

我试过这个。不确定它是否正确。

   SELECT DISTINCT dr.*
                FROM MyTable dr
                inner join(
                    SELECT ID, Name, Addr
                    FROM MyTable
                    GROUP BY ID, Name, Addr
                ) ss on dr.Name = ss.Name and 
                        dr.Addr = ss.Addr and 
                        dr.ID <> ss.ID 
                order by Name

3 个答案:

答案 0 :(得分:5)

编辑添加tDate后完成更改,需要两个结果集

结果集1:

SELECT
    id, Name, Addr, tDate
FROM
(
    SELECT
        *,
        COUNT(*) OVER (PARTITION BY Name, Addr)   AS occurrences
    FROM
        MyTable
)
    AS parsed
WHERE
   occurrences > 1

结果集2:

SELECT
    *,
    FIRST_VALUE(ID) OVER (PARTITION BY Name, Addr
                              ORDER BY tDate DESC
                               ROWS UNBOUNDED PRECEDING)   AS nID
FROM
    MyTable
ORDER BY
    ID

示例:http://sqlfiddle.com/#!6/9285ae/9

答案 1 :(得分:1)

dense_rank窗口函数应该可以解决问题:

SELECT   ID, Name, Addr
         DENSE_RANK() OVER (PARTITION BY Name, Addr ORDER BY ID) AS nID
FROM     mytable
ORDER BY 1, 4

答案 2 :(得分:-1)

你应该使用没有分区的RANK

SELECT   ID, Name, Addr,
         RANK() OVER (ORDER BY Id,name,addr) AS nID
FROM     table