在 case 语句中使用 distinct
use distinct within case statement
我有一个查询使用多个左联接并试图从其中一个联接列中获取值的总和。
SELECT
SUM( case when session.usersessionrun =1 then 1 else 0 end) new_unique_session_user_count
FROM session
LEFT JOIN appuser ON appuser.appid = '6279df3bd2d3352aed591583'
AND appuser.userid = session.userid
LEFT JOIN userdevice ON userdevice.appid = '6279df3bd2d3352aed591583'
AND userdevice.userid = appuser.userid
WHERE session.appid = '6279df3bd2d3352aed591583'
AND (session.uploadedon BETWEEN '2022-04-18 08:31:26' AND '2022-05-18 08:31:26')
但这显然给出了多余的 session.usersessionrun=1
计数,因为它是一个合并的结果集。
如果该记录的会话运行是 1
。
,这里的逻辑是将用户标记为 new
我按userid
和usersessionrun
分组,显示记录重复
userid. sessionrun. count
628212 1 2
627a01 1 4
所以我想做的是
SUM(CASE distinct(session.userid) AND WHEN session.usersessionrun = 1 THEN 1 ELSE 0 END) new_unique_session_user_count
即对于每个唯一用户数,session.usersessionrun = 1 应该只执行一次。
如您所见,JOIN 操作会产生数据的组合爆炸。
您需要一个子查询来按用户 ID 计算您的会话。然后您可以将子查询视为虚拟 table 并将其加入其他 table 以获取结果集中所需的信息。
子查询(我的答案中没有任何调试):
SELECT COUNT(*) new_unique_session_user_count,
session.userid
FROM session
WHERE session.appid = '6279df3bd2d3352aed591583'
AND session.uploadedon BETWEEN '2022-04-18 08:31:26'
AND '2022-05-18 08:31:26'
AND session.usersessionrun = 1
AND session.appid = '6279df3bd2d3352aed591583'
GROUP BY userid
此子查询总结了您的会话 table 并且每个用户 ID 一行。避免 JOIN-created 组合爆炸的技巧是使用子查询生成结果,每个数据项在 JOIN 的 ON-clause.
中提到只有一行
然后,你像这样table加入其他
SELECT summary.new_unique_session_user_count
FROM (
SELECT COUNT(*) new_unique_session_user_count,
session.userid
FROM session
WHERE session.appid = '6279df3bd2d3352aed591583'
AND session.uploadedon BETWEEN '2022-04-18 08:31:26'
AND '2022-05-18 08:31:26'
AND session.usersessionrun = 1
AND session.appid = '6279df3bd2d3352aed591583'
GROUP BY userid
) summary
JOIN appuser ON appuser.appid = '6279df3bd2d3352aed591583'
AND appuser.userid = summary.userid
JOIN userdevice ON userdevice.appid = '6279df3bd2d3352aed591583'
AND userdevice.userid = appuser.userid
可能有更好的方法来构造此查询,但如果没有关于您的 table 定义和业务规则的更多信息,很难猜测它们。
我有一个查询使用多个左联接并试图从其中一个联接列中获取值的总和。
SELECT
SUM( case when session.usersessionrun =1 then 1 else 0 end) new_unique_session_user_count
FROM session
LEFT JOIN appuser ON appuser.appid = '6279df3bd2d3352aed591583'
AND appuser.userid = session.userid
LEFT JOIN userdevice ON userdevice.appid = '6279df3bd2d3352aed591583'
AND userdevice.userid = appuser.userid
WHERE session.appid = '6279df3bd2d3352aed591583'
AND (session.uploadedon BETWEEN '2022-04-18 08:31:26' AND '2022-05-18 08:31:26')
但这显然给出了多余的 session.usersessionrun=1
计数,因为它是一个合并的结果集。
如果该记录的会话运行是 1
。
new
我按userid
和usersessionrun
分组,显示记录重复
userid. sessionrun. count
628212 1 2
627a01 1 4
所以我想做的是
SUM(CASE distinct(session.userid) AND WHEN session.usersessionrun = 1 THEN 1 ELSE 0 END) new_unique_session_user_count
即对于每个唯一用户数,session.usersessionrun = 1 应该只执行一次。
如您所见,JOIN 操作会产生数据的组合爆炸。
您需要一个子查询来按用户 ID 计算您的会话。然后您可以将子查询视为虚拟 table 并将其加入其他 table 以获取结果集中所需的信息。
子查询(我的答案中没有任何调试):
SELECT COUNT(*) new_unique_session_user_count,
session.userid
FROM session
WHERE session.appid = '6279df3bd2d3352aed591583'
AND session.uploadedon BETWEEN '2022-04-18 08:31:26'
AND '2022-05-18 08:31:26'
AND session.usersessionrun = 1
AND session.appid = '6279df3bd2d3352aed591583'
GROUP BY userid
此子查询总结了您的会话 table 并且每个用户 ID 一行。避免 JOIN-created 组合爆炸的技巧是使用子查询生成结果,每个数据项在 JOIN 的 ON-clause.
中提到只有一行然后,你像这样table加入其他
SELECT summary.new_unique_session_user_count
FROM (
SELECT COUNT(*) new_unique_session_user_count,
session.userid
FROM session
WHERE session.appid = '6279df3bd2d3352aed591583'
AND session.uploadedon BETWEEN '2022-04-18 08:31:26'
AND '2022-05-18 08:31:26'
AND session.usersessionrun = 1
AND session.appid = '6279df3bd2d3352aed591583'
GROUP BY userid
) summary
JOIN appuser ON appuser.appid = '6279df3bd2d3352aed591583'
AND appuser.userid = summary.userid
JOIN userdevice ON userdevice.appid = '6279df3bd2d3352aed591583'
AND userdevice.userid = appuser.userid
可能有更好的方法来构造此查询,但如果没有关于您的 table 定义和业务规则的更多信息,很难猜测它们。