3

次のSQLステートメント:

SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND historyIdCode = 'statusChanged' 
ORDER BY h.whenCreated

次の出力が得られます。最新のstatusChangedIdCodeを持つ1行のみを返すように変更するにはどうすればよいですか?

ここに画像の説明を入力してください

4

4 に答える 4

6
SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND h.historyIdCode = 'statusChanged' 
  AND h.whenCreated = (select max(whenCreated)
                       from dpod_site_historyItems h2
                       where h2.itemId = h.itemId
                         and h2.historyIdCode = 'statusChanged')
ORDER BY h.whenCreated

または、ウィンドウ関数をサポートする最新のDBMSがある場合:

SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN (
     select itemid, 
            historyIdCode,
            whenCreated,
            statusChangedIdCode,
            row_number() over (partition by itemid order by whenCreated desc) as rn 
     from dpod_site_historyItems 
     where historyIdCode = 'statusChanged' 
   ) h ON f.id = h.itemId AND h.rn = 1
WHERE f.id = 216 
ORDER BY h.whenCreated

dpod_site_flashcards.idどちらの場合も、LIMITソリューションでは機能しない複数の行を選択した場合にも機能します。

于 2013-01-09T20:48:39.997 に答える
3

これを試しましたか?

SELECT f.id, f.front, f.back, h.statusChangedIdCode, MAX(h.whenCreated), h.historyIdCode 
FROM dpod_site_flashcards AS f 
JOIN dpod_site_historyItems AS h ON f.id=h.itemId 
WHERE f.id = 216 AND historyIdCode='statusChanged' 
GROUP BY f.id, f.front, f.back, h.statusChangedIdCode, h.historyIdCode 

-編集

おっと、ありがとう@Gordon、要件を十分に読んでいませんでした。これは、仕事をするべきいくつかのSQLFiddleです。

正しいコードのスニペットを次に示します。これを WHERE 句に含めます。

h.whenCreated = (select max(whenCreated)
   from dpod_site_historyItems h2
   where h2.itemId = h.itemId)
于 2013-01-09T20:40:43.870 に答える
1

MySQL を使用する場合は、末尾を次のように変更します。ORDER BY h.whenCreated DESC LIMIT 1

于 2013-01-09T20:40:59.770 に答える
1

これは @itchy の回答に基づいています。最良の答えは、データベースによって異なります。

一部のデータベースは をサポートlimitしているため、答えは次のとおりです。

SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND historyIdCode = 'statusChanged' 
ORDER BY h.whenCreated
limit 1

SQL Server と Sybase のサポートtopにより、次の結果が得られます。

SELECT top 1 f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND historyIdCode = 'statusChanged' 
ORDER BY h.whenCreated

Oracle は rownum を使用しますが、サブクエリが必要です。

select * from (SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND historyIdCode = 'statusChanged' 
ORDER BY h.whenCreated
) t
where rownum = 1

DB2 は fetch_first を使用します。

SELECT f.id, 
       f.front, 
       f.back, 
       h.statusChangedIdCode, 
       h.whenCreated,
       h.historyIdCode 
FROM dpod_site_flashcards AS f 
   JOIN dpod_site_historyItems AS h ON f.id = h.itemId 
WHERE f.id = 216 
  AND historyIdCode = 'statusChanged' 
ORDER BY h.whenCreated
fetch first 1 row only
于 2013-01-09T21:05:21.793 に答える