将单独的SQL查询组合在一起填充空白

时间:2013-10-10 11:17:16

标签: sql

我正在尝试创建一个将3个查询的结果组合在一起的SQL查询。

这个想法是让前1000名用户获得新消息和/或请求和/或通知,然后每周向他们发送一封邮件。

注意:我正在使用MS SQL Server。

我有3个单独的复杂查询(我在这里简化了),例如:

'Get all users with new messages:
SELECT mbrid, messageCount
FROM tblMessages
WHERE messageCount > 0

'Get all users with new notifications:
SELECT mbrid, notificationCount
FROM tblNotifications
WHERE notificationCount > 0

'Get all users with new requests:
SELECT mbrid, requestCount
FROM tblRequests
WHERE requestCount > 0

我想将所有3个组合成1个表,并选择TOP 1000记录。

例如

如果每个查询都返回:

mbrID    messageCount
---------------------
2        20
3        2

mbrID    notificationCount
---------------------
1        1
3        2

mbrID    requestCount
---------------------
3        2

我想结合3个结果来创建一个像这样的表:

mbrID    messageCount    notificationCount    requestCount
----------------------------------------------------------
1        0               1                    0
2        20              0                    0
3        2               2                    2

请注意,组合结果应填充缺少的空白行,例如:0

这甚至可能吗?

如果有数百万条记录,我想这将是非常低效的。 是否有更好的方法可以做到这一点?

更新

这是我最终选择的(@Upendra Chaudhari解决方案), 感谢大家的帮助。

SELECT TOP (1000)
    mbrID, 
    SUM(messageCount) AS messageCount, 
    SUM(notificationCount) AS notificationCount, 
    SUM(requestCount) AS requestCount 
FROM (

    SELECT TOP (1000)
            mbrID,
            messageCount,
            0 AS notificationCount,
            0 AS requestCount
    FROM 
            usrv_CommMessagesNew
    ORDER BY
            mbrID

    UNION

    SELECT TOP (1000)
            mbrID,
            0 AS messageCount,
            notificationCount,
            0 AS requestCount
    FROM 
            usrv_CommNotificationsNew
    ORDER BY
            mbrID

    UNION

    SELECT TOP (1000)
            mbrID,
            0 AS messageCount,
            0 AS notificationCount,
            requestCount
    FROM 
            usrv_CommRequestsNew
    ORDER BY
            mbrID

    ) AS tblTemp

GROUP BY
    mbrID

TOP 1000条款限制了结果以提高性能。

因此,messageCount优先,然后是notificationCount,然后是requestCount。

这意味着数据可能不包含notificationCount或requestCount的所有行 - 在这个实例中我很好 - 它针对性能而非优化。

3 个答案:

答案 0 :(得分:0)

尝试这样的UNION:

    SELECT  mbrid, SUM(messageCount), SUM(notificationCount), SUM(requestCount)
FROM    (
            SELECT mbrid, messageCount, 0 AS notificationCount, 0 AS requestCount
            FROM tblMessages
            WHERE messageCount > 0

            UNION

            SELECT mbrid, 0 AS messageCount, notificationCount, 0 AS requestCount
            FROM tblNotifications
            WHERE notificationCount > 0

            UNION

            SELECT mbrid, 0 AS messageCount, 0 AS notificationCount, requestCount
            FROM tblRequests
            WHERE requestCount > 0
        ) TempTable
GROUP BY mbrid

答案 1 :(得分:0)

好奇,一旦你把所有三张桌子“联合”在一起,你将如何决定哪些记录是前1000名呢?

如果您打算同样对待邮件,通知和请求,那么以下内容可能是您正在寻找的答案:

SELECT TOP 1000 * FROM
(SELECT mbrid, messageCount as Count
FROM tblMessages
WHERE messageCount > 0
UNION ALL
SELECT mbrid, notificationCount as Count
FROM tblNotifications
WHERE notificationCount > 0
UNION ALL
SELECT mbrid, requestCount as Count
FROM tblRequests
WHERE requestCount > 0
ORDER BY Count DESC) d

有关UNION和UNION ALL运算符的更多信息,请参阅this Wikipedia page

答案 2 :(得分:0)

如果您想使用COALESCE,则必须使用OUTER JOIN,这应该没问题:

SELECT COALESCE(m.mbrid, r.mbrid, n.mbrid) AS mbrid, ISNULL(m.messageCount,0) AS messageCount, ISNULL(n.NotificationCount,0) AS NotificationCount, ISNULL(r.requestCount, 0) AS requestCount
FROM tblMessages m
FULL JOIN tblNotifications n
    ON m.mbrid = n.mbrid
    AND m.messageCount > 0
    AND n.notificationCount > 0
FULL JOIN tblRequests r
    ON m.mbrid = r.mbrid
    AND r.requestCount > 0  
ORDER BY mbrid

导致完全符合您的要求:

| MBRID | MESSAGECOUNT | NOTIFICATIONCOUNT | REQUESTCOUNT |
|-------|--------------|-------------------|--------------|
|     1 |            0 |                 1 |            0 |
|     2 |           20 |                 0 |            0 |
|     3 |            2 |                 2 |            2 |

你可以看到here