加入两个SQL表(唯一值)

时间:2013-01-15 13:01:04

标签: sql sql-server distinct-values

我的SQL Server数据库中有两个表要加入:

人员表:

PersonId   Name    DeviceId
001        John    11111
002        Eric    22222
003        Steve   33333

设备表:

DeviceId  Date
11111     2013-02-01
11111     2013-02-02
11111     2013-02-03
22222     2013-02-03
22222     2013-02-01

我想要的结果是以下

PersonId   Name   DeviceId  Date         IsRegistered
001        John   11111     2013-02-03       1
002        Eric   22222     2013-02-03       1
003        Steve  33333     null             0

因此,当你看到我希望表之间的连接时,我只想要唯一的值。 数据字段应该是最后注册的(最新日期)。如果此人在日期字段中有值,则IsRegistered应具有值0

如果有人知道如何解决这个问题我会很感激

2 个答案:

答案 0 :(得分:4)

查询:

SELECT 
  p.*, d.maxdate
FROM persons p
left join
(  SELECT id, MAX(date) MaxDate
   FROM device   
   GROUP BY id
) d  ON p.deviceid = d.id
     ORDER BY d.maxdate DESC;



| PERSONID |  NAME | DEVICEID |                         MAXDATE |
-----------------------------------------------------------------
|        1 |  John |    11111 | February, 03 2013 02:00:00+0000 |
|        2 |  Eric |    22222 | February, 03 2013 00:00:00+0000 |
|        3 | Steve |    33333 |                          (null) |

我发现您还需要isRegistered列,此处为:

  • 添加了最后一列的SQLFIDDLE

查询:

SELECT 
    p.*, d.maxdate, case when d.maxdate is null then 0 else 1 end as isRegistered
    FROM persons p
    left join
    (  SELECT id, MAX(date) MaxDate
       FROM device   
       GROUP BY id
    ) d  ON p.deviceid = d.id
         ORDER BY d.maxdate DESC
    ;

结果:

| PERSONID |  NAME | DEVICEID |                         MAXDATE | ISREGISTERED |
--------------------------------------------------------------------------------
|        1 |  John |    11111 | February, 03 2013 02:00:00+0000 |            1 |
|        2 |  Eric |    22222 | February, 03 2013 00:00:00+0000 |            1 |
|        3 | Steve |    33333 |                          (null) |            0 |

答案 1 :(得分:1)

试试这个:

SELECT 
  p.PersonId,
  p.Name,
  p.DeviceId,
  d.MaxDate AS "Date",
  CASE 
    WHEN d.deviceID IS NULL THEN 0 
    ELSE 1 
  END AS IsRegistred
FROM Person  p
LEFT JOIN
(
  SELECT  DeviceId, MAX(Date) MaxDate
  FROM Device
  GROUP BY DeviceId
) d ON p.DeviceId = d. DeviceId;

SQL Fiddle Demo

这会给你:

| PERSONID |  NAME | DEVICEID |                            DATE | ISREGISTRED |
-------------------------------------------------------------------------------
|        1 |  John |    11111 | February, 03 2013 02:00:00+0000 |           1 |
|        2 |  Eric |    22222 | February, 03 2013 02:00:00+0000 |           1 |
|        3 | Steve |    33333 |                          (null) |           0 |

或:使用排名功能ROW_NUMBER()即可:

WITH CTE
AS
(
    SELECT
      p.PersonId,
      p.Name,
      p.DeviceId,
      d.deviceID AS ddeviceID,
      d.Date,
      ROW_NUMBER() OVER(PARTITION BY p.PersonID, p.DeviceId 
                        ORDER BY Date DESC) rownum
    FROM Person p
    LEFT JOIN Device d ON p.DeviceId = d. DeviceId
) 
SELECT
  PersonID,
  Name,
  DeviceId,
  Date,
  CASE 
    WHEN ddeviceID IS NULL THEN 0 
    ELSE 1 
  END AS IsRegistred
FROM CTE
WHERE  rownum = 1;

Updated SQL Fiddle Demo

这会给你相同的结果。