我问a related question我得到了一些非常好的答案,但是我试图在不制作临时表的情况下进行查询。我相信它可以做到,但我无法弄清楚如何去做。
我有两个表,我希望获得每个条目的最新状态,其中状态日期小于或等于输入日期。
条目表(条目):
UserID | EntryDate
----------------------
1 | 5/4/2010
1 | 4/4/2010
1 | 3/4/2010
1 | 2/4/2010
2 | 5/4/2010
2 | 4/4/2010
条目状态表(状态):
UserID | StatusDate | Detail
-------------------------------
1 | 5/28/2010 | D-1
1 | 4/24/2010 | D-2
1 | 4/5/2010 | D-3
1 | 2/28/2010 | D-4
预期输出:
UserID | EntryDate | Detail
---------------------------
1 | 5/4/2010 | D-2
1 | 4/4/2010 | D-4
1 | 3/4/2010 | D-4
1 | 2/4/2010 | <NULL>
在我的previous question中,您可以看到我的努力和相关答案,但我已经缩小了问题范围以简化问题。
我试图做这样的事情(但我知道我必须离开):
SELECT E.EntryDate,
S.Detail,
MAX(S.StatusDate) AS MaxStatusDate
FROM Entry AS E
LEFT OUTER JOIN Status AS S ON E.EntryDate >= S.StatusDate
答案 0 :(得分:3)
我想你想要像
这样的东西SELECT E.UserID
, E.EntryDate
, (SELECT TOP 1 Detail
FROM Status AS S
WHERE S.UserID = E.UserID
AND S.StatusDate <= E.EntryDate
ORDER BY S.StatusDate DESC)
FROM Entry AS E
如果您的数据库不支持TOP
或出于性能原因,您宁愿避免ORDER BY
尝试类似的内容:
SELECT E.UserID
, E.EntryDate
, (SELECT S1.Detail
FROM Status AS S1
WHERE S1.UserID = E.UserID
AND S1.StatusDate = (SELECT MAX(S2.StatusDate)
FROM Status AS S2
WHERE S2.UserID = E.UserID
AND S2.StatusDate <= E.EntryDate))
FROM Entry AS E
答案 1 :(得分:1)
我不认为这是一种通用的方法,但在某些SQL方言中,您可以在子查询中使用TOP或LIMIT从第一个匹配记录中的列中获取值在另一列的排序(ORDER BY)上。
例如......
SELECT
Entry.*,
( SELECT TOP 1
Status.Detail
FROM Status
WHERE
Entry.UserID = Status.UserID AND
Entry.EntryDate >= Status.StatusDate
ORDER BY
Entry.EntryDate
) As StatusDetail
答案 2 :(得分:1)
row_number
方式,适用于支持它的数据库:
SELECT *
FROM (
SELECT ROW_NUMBER() OVER (
PARTITION BY e.UserId, e.EntryDate
ORDER BY s.StatusDate desc) as rn
, *
FROM Entry e
INNER JOIN
Status s
ON s.UserID = e.UserID
AND s.StatusDate <= e.EntryDate
) as SubQueryAlias
where rn = 1
答案 3 :(得分:1)
SELECT
e.UserID,
e.EntryDate,
s.Detail
FROM Entry e
INNER JOIN (SELECT DISTINCT UserID FROM Status) u
ON e.UserID = u.UserID
LEFT JOIN (
SELECT
e.UserID,
e.EntryDate,
MAX(s.StatusDate) AS StatusDate
FROM Entry e
INNER JOIN Status s
ON e.UserID = s.UserID AND e.EntryDate >= s.StatusDate
GROUP BY e.UserID, e.EntryDate
) sd
ON e.UserID = sd.UserID AND e.EntryDate = sd.EntryDate
LEFT JOIN Status s
ON sd.UserID = s.UserID AND sd.StatusDate = s.StatusDate
不同用户列表用于过滤掉Entry
中未在Status
中显示的用户。
然后,结果集与派生表连接,该派生表包含与输入日期对应的最大状态日期值。
最后再次加入Status
表,这次是为了获取详细信息。
最后两个连接是左连接,因此结果集将包含Entry
中Status
的每个用户的所有行,并且内连接保证所有用户都不会其他人。