如何使SQL联接只返回一行最新的状态代码?
以下SQL语句:如何使SQL联接只返回一行最新的状态代码?,sql,sqlite,Sql,Sqlite,以下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 histo
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?
你试过这个吗
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
-编辑
哦,谢谢,没有仔细阅读需求。这里有一些应该做这项工作
以下是正确代码的剪贴画——请将其包含在WHERE子句中:
h.whenCreated = (select max(whenCreated)
from dpod_site_historyItems h2
where h2.itemId = h.itemId)
如果使用MySQL,请将结尾更改为:
orderbyh.whenCreated DESC LIMIT 1
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\u site\u flashcard.id
选择行时,这两种情况都会起作用,而限制解决方案不会这样做。这是基于@itchy的答案。最佳答案取决于数据库
一些数据库支持限制
,因此答案是:
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_:
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
这可能是一个特定于数据库的解决方案,它肯定不会在大多数数据库中工作。请发布它将在哪个数据库上工作。根据数据库的不同,语法可能是
SELECT top 1
或其中rownum=1
。这不会返回正确答案。问题是查找一行,而不是每个StatusChangedCode的单独一行。为什么这样不正确的答案会获得选票?谢谢——读得太快,请参阅编辑,发布到修订sql的链接。我非常理解这个问题的错误(这里有很多经验)。我不明白的是投票结果。通常,我不会因为误解而对某人投反对票,只是因为对SQL的过分使用。为什么不在这个答案中包含SQLFIDLE语句呢?我想你忘了在你的子选择中过滤historydcode
。@Neil:那是在外部查询中完成的。但你说得有道理。它可能应该在内部完成query@a_horse_with_no_name我担心MAX(创建时)
会为historydcode
不是'statusChanged'
的行选择日期。