我正在尝试创建一个将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的所有行 - 在这个实例中我很好 - 它针对性能而非优化。
答案 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。