棘手的SQL选择

时间:2014-09-16 18:14:56

标签: mysql sql stored-procedures join

我有一个消息表,该表包含以下列:

id | fromUserId | toUserId | sentDate | readDate | message | subject | fromUserDeleted(bit) | toUserDeleted(bit)

现在我需要在每个转换中选择第一条消息,如果它来自或当前用户。更复杂的是我需要排除当前用户删除的消息,因此如果消息来自当前用户,那么如果消息来自另一个用户则fromUserDeleted必须为0,那么toUserDeleted必须为0。 / p>

我知道已经有很多关于如何在组内选择第一篇文章的例子,但这有点复杂。当前用户可能位于toUserId或fromUserId中,删除列也是如此。

这就是我的尝试:

SELECT 
    m1.*, 
    (SELECT count(*) FROM mail m3 WHERE m3.fromUserId=m1.fromUserId AND m3.toUserId=m1.toUserId AND m3.toUserDeleted = 0) as messageCount, 
    (SELECT count(*) FROM mail m4 WHERE m4.toUserId=15 AND m4.readDate is null AND m4.toUserDeleted=0) as messagesNotRead 
FROM 
    mail m1 
LEFT JOIN mail m2 ON 
    ((m1.fromUserId = m2.fromUserId) and
    m2.)
WHERE 
    m2.id IS NULL AND 
    (m1.toUserId = 15 OR m1.fromUserId = 15) 
ORDER BY 
    m1.sentDate DESC;

并且:

SELECT 
    * 
FROM 
    mail m1
WHERE
    ((m1.fromUserId = 15 AND m1.fromUserDeleted=0) OR (m1.toUserId = 15 AND m1.toUserDeleted=0)) AND
    m1.id = (SELECT m2.id FROM mail m2 WHERE m2.fromUserId = 15 OR m2.toUserId = 15 OR m2.fromUserId = m1.fromUserId OR m2.fromUserId = m1.toUserId OR m2.toUserId = m1.fromUserId OR m2.toUserId = m1.toUserId order By m2.sentDate desc limit 0,1)
Order by m1.sentDate DESC

这些都不会满足我的需要。请帮忙!

如果需要创建存储过程,那也没关系。

重要提示:这是我的MySQL

编辑1:

请见例如:http://sqlfiddle.com/#!2/6a2ef/3

2 个答案:

答案 0 :(得分:0)

感谢您的反馈。希望这能满足您的需求:

DECLARE @UserID INT
SELECT @UserID = 15

SELECT *
FROM (
    SELECT UserID, ConversationWithUserID, sentDate, readDate, [message], [subject], ROW_NUMBER() OVER (PARTITION BY ConversationWithUserID ORDER BY sentDate ASC) AS MessageOrder
    FROM (
        SELECT id, fromUserId AS UserID, toUserId AS ConversationWithUserID, sentDate, readDate, [message], [subject]
        FROM dbo.mail
        WHERE fromUserID = @UserID AND fromUserDeleted = 0
        UNION
        SELECT id, toUserId AS UserID, fromUserId AS ConversationWithUserID, sentDate, readDate, [message], [subject]
        FROM dbo.mail
        WHERE toUserId = @UserID AND toUserDeleted = 0
    ) x
) y
WHERE MessageOrder = 1
ORDER BY y.UserID, y.ConversationWithUserID

答案 1 :(得分:0)

让UNPIVOT从同一列下的fromUerId,toUserId获取,以便我们可以根据sentDate选择正确的userId。

SELECT T.*

FROM
(
    SELECT *,

           ROW_NUMBER() OVER ( PARTITION BY userVal ORDER BY sentDate DESC) as seq
    FROM
    (SELECT 
            *

     FROM msg
     WHERE (fromUserId = @userID AND fromUserDeleted = 0 ) 
           OR  (toUserId = @UserID AND toUserDeleted = 0)

    )p
    unpivot
    ( userVal for UserId in ( fromUserId, toUserId)
    )as unpvt
) T
WHERE seq =1