我有一个包含不同消息的表,每个消息都有一个messageType字段。我需要为每个messageType填充上次加载的消息的ASP.NET列表控件。我的sql语句返回一切是:
SELECT MessageTypes.MessageType MessageType
,Messages.MessageDate
,Messages.ValueDate
,Messages.MessageReference
,Messages.Beneficiary
,Messages.StatusId
,MessageStatus.STATUS
,BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE (BICProfile.BIC = 'someValue')
AND Messages.StatusId IN (4, 5, 6)
所以我需要为每种消息类型提取最后一条消息。
修改 的 关于statusId的一些说明。这些基本上与用户角色一起使用,可以看到哪些消息。所以,我需要为给定的消息类型返回最后加载的消息。实际上,只希望为每种消息类型返回1条消息。 messageId是唯一的,消息日期可以是相同的。
答案 0 :(得分:2)
您可以使用ROW_NUMBER()函数按邮件日期为每条邮件分配排名(对于每种邮件类型,再次从1开始),然后将结果限制为排名靠前的邮件:
WITH AllMessages AS
( SELECT MessageTypes.MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.Status,
BICProfile.BIC,
RowNumber = ROW_NUMBER() OVER(PARTITION BY Messages.MessageTypeId
ORDER BY Messages.MessageDate DESC)
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
)
SELECT MessageType,
MessageDate,
ValueDate,
MessageReference,
Beneficiary,
StatusId,
Status,
BIC
FROM AllMessages
WHERE RowNumber = 1;
如果您无法使用ROW_NUMBER
,则可以使用子查询获取每种类型的最新消息日期:
SELECT Messages.MessageTypeID, MessageDate = MAX(Messages.MessageDate)
FROM Messages
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
GROUP BY Messages.MessageTypeID
然后将内容加入到您的主要查询中以过滤结果:
SELECT MessageTypes.MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.Status,
BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
INNER JOIN
( SELECT Messages.MessageTypeID,
MessageDate = MAX(Messages.MessageDate)
FROM Messages
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
GROUP BY Messages.MessageTypeID
) AS MaxMessage
ON MaxMessage.MessageTypeID = Messages.MessageTypeID
AND MaxMessage.MessageDate = Messages.MessageDate
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6);
N.B如果最新消息日期在多个消息中很常见,则第二种方法将为每种消息类型返回多行。通过将ROW_NUMBER
替换为RANK
修改强>
如果您有多个具有相同日期的消息并且只想返回其中一个消息,则需要在row_number函数中扩展排序,即如果您想在有关系时选择具有最大ID的消息做到:
RowNumber = ROW_NUMBER() OVER(PARTITION BY Messages.MessageTypeId
ORDER BY Messages.MessageDate DESC,
Messages.MessageID DESC)
所以完整的查询将是:
WITH AllMessages AS
( SELECT MessageTypes.MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.Status,
BICProfile.BIC,
RowNumber = ROW_NUMBER() OVER(PARTITION BY Messages.MessageTypeId
ORDER BY Messages.MessageDate DESC,
Messages.MessageID DESC)
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
)
SELECT MessageType,
MessageDate,
ValueDate,
MessageReference,
Beneficiary,
StatusId,
Status,
BIC
FROM AllMessages
WHERE RowNumber = 1;
答案 1 :(得分:2)
试试这个:
SELECT MT.MessageType
,X.MessageDate
,X.ValueDate
,X.MessageReference
,X.Beneficiary
,X.StatusId
,X.STATUS
,X.BIC
FROM MessageTypes MT
OUTER APPLY -- or CROSS APPLY
(
SELECT TOP 1
M.MessageDate
,M.ValueDate
,M.MessageReference
,M.Beneficiary
,M.StatusId
,MS.STATUS
,B.BIC
FROM Messages M
INNER JOIN MessageStatus MS
ON M.StatusId = MS.Id
INNER JOIN BICProfile B
ON M.SenderId = B.BicId
WHERE (B.BIC = 'someValue')
AND M.StatusId IN (4, 5, 6)
AND M.MessageTypeId = MT.MessageTypeId
ORDER BY M.MessageDate DESC
) X
答案 2 :(得分:0)
您可以使用简单的子查询来获取每种消息类型的最新消息日期,并使用它来过滤最后一条消息。见下文:
如果您想要每个类别的最后一条消息,请仅显示该消息的状态为4,5或6 :(如果消息的状态为其他类别,则该类别无效)
SELECT MessageTypes.MessageType MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.STATUS,
BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
and messages.messagedate =
(select max(x.messagedate)
from messages x
where x.messagetypeid = messages.messagetypeid)
如果您想要每个类别的最后一条消息,只需要该消息的状态为4,5或6 :(如果消息的状态是其他类型,那么该类别没有结果)AND IN THE一个领带的事件你想要有最高的消息ID的消息
SELECT MessageTypes.MessageType MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.STATUS,
BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
and messages.messagedate =
(select max(x.messagedate)
from messages x
where x.messagetypeid = messages.messagetypeid)
and messages.messageid =
(select max(x.messageid)
from messages x
where x.messagetypeid = messages.messagetypeid
and x.messagedate = messages.messagedate)
^^ CHANGE“messageid”到表格上的任何字段MESSAGES表示ID。
如果您希望每个类别的最后一条消息以及每个状态为4,5和6(如果该类别中存在任何/全部)
SELECT MessageTypes.MessageType MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.STATUS,
BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
and messages.messagedate =
(select max(x.messagedate)
from messages x
where x.messagetypeid = messages.messagetypeid
and x.statusid = messages.statusid)
如果您想要状态为4,5或6的每个类别的最后一条消息:(未考虑其他状态的消息)
SELECT MessageTypes.MessageType MessageType,
Messages.MessageDate,
Messages.ValueDate,
Messages.MessageReference,
Messages.Beneficiary,
Messages.StatusId,
MessageStatus.STATUS,
BICProfile.BIC
FROM Messages
INNER JOIN MessageStatus
ON Messages.StatusId = MessageStatus.Id
INNER JOIN MessageTypes
ON Messages.MessageTypeId = MessageTypes.MessageTypeId
INNER JOIN BICProfile
ON Messages.SenderId = dbo.BICProfile.BicId
WHERE BICProfile.BIC = 'someValue'
AND Messages.StatusId IN (4, 5, 6)
and messages.messagedate =
(select max(x.messagedate)
from messages x
where x.messagetypeid = messages.messagetypeid
and x.statusid in (4, 5, 6))