0

SQL Server データベースに、結合したい 2 つのテーブルがあります。

人物表:

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 でなければなりません

誰かがこれを修正する方法を知っているなら、私はそれを感謝します

4

2 に答える 2

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 WITH 最後の列が追加されました

クエリ:

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 |
于 2013-01-15T13:10:35.850 に答える
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 フィドルのデモ

これにより、次のことが得られます。

| 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;

更新された SQL Fiddle デモ

これにより、同じ結果が得られます。

于 2013-01-15T13:04:18.030 に答える