Sql查询以在同一查询中查找条件不同的计数和总计数
这是我的样品表Sql查询以在同一查询中查找条件不同的计数和总计数,sql,postgresql,amazon-redshift,postgresql-8.4,Sql,Postgresql,Amazon Redshift,Postgresql 8.4,这是我的样品表 Logs user_id, session_id, search_query, action 1, 100, dog, A 1, 100, dog, B 2, 101, cat, A 3, 102, ball, A 3, 102, ball, B 3, 102, kite, A 4, 103, ball, A 5, 104, cat, A 在哪里 未命中=对于相同的用户id和相同的会话id,如果操作A后面没有操作B,则称为未命中。 注意:动作B只能在动作A发生后发生 我能够找
Logs
user_id, session_id, search_query, action
1, 100, dog, A
1, 100, dog, B
2, 101, cat, A
3, 102, ball, A
3, 102, ball, B
3, 102, kite, A
4, 103, ball, A
5, 104, cat, A
在哪里
未命中=对于相同的用户id和相同的会话id,如果操作A后面没有操作B,则称为未命中。
注意:动作B只能在动作A发生后发生
我能够找到所有用户和会话中每个唯一搜索查询的未命中计数
SELECT l1.search_query, count(l1.*) as misses
FROM logs l1
WHERE NOT EXISTS
(SELECT NULL FROM logs l2
WHERE l1.user_id = l2.user_id
AND l1.session_id = l2.session_id
AND l1.session_id != ''
AND l2.action = 'B'
AND l1.action = 'A')
AND l1.action='A'
AND l1.search_query != ''
GROUP BY v1.search_query
order by misses desc;
对于每个唯一的搜索查询,我试图查找未命中百分比=未命中数/总行数*100的值。我不知道如何在同一个查询中找到带条件的计数和不带条件的计数。任何帮助都会很好
expected output:
cat 100
kite 100
ball 50
一种方法是将EXISTS移到count中
SELECT l1.search_query, count(case when NOT EXISTS
(SELECT 1 FROM logs l2
WHERE l1.user_id = l2.user_id
AND l1.session_id = l2.session_id
AND l1.search_query = l2.search_query
AND l2.action = 'B'
AND l1.action = 'A') then 1 else null end
)*100.0/count(*) as misses
FROM logs l1
WHERE l1.action='A'
AND l1.search_query != ''
GROUP BY l1.search_query
order by misses desc;
这将产生所需的结果,但如果没有发现未命中,也会产生零。这可以通过HAVING子句或后处理来删除
注意:我还添加了缺失的l1.search\u query=l2.search\u query子句,因为在同一会话中有一行包含B,所以它被视为已成功。您可以始终创建两个查询,并使用联接将它们合并为一个查询。然后可以在桥接或连接SQL语句中进行计算 在MS-SQL兼容SQL中,这将是:
SELECT ActiontypeA,countedA,isNull(countedB,0) as countedB,
(countedA-isNull(countedB,0))*100/CountedA as missed
FROM (SELECT search_query as actionTypeA, count(*) as countedA
FROM logs WHERE Action='A' GROUP BY actionType
) as TpA
LEFT JOIN
(SELECT search_query as actionTypeB, count(*) as countedB
FROM logs WHERE Action='B' GROUP BY actionType
) as TpB
ON TpA.ActionTypeA = TpB.ActiontypeB
需要使用左联接从“A”结果中选择所有活动搜索查询,并仅将其联接到“B”结果中有“B”可用的活动。
因为这是非常基本的SQL,并且经过SQL引擎的优化,所以我建议尽可能地防止WHERE的存在。IsNull函数是一个MS-SQL函数,用于将NULL值强制转换为可用于计算的int0值
最后你可以过滤了
WHERE missed>0
要得到最终结果。我认为您只需要在这里使用case语句。如果我对你的问题理解正确的话。。那么解决办法是这样的-
WITH summary
AS (
SELECT user_id
,session_id
,search_query
,count(1) AS total_views
,sum(CASE
WHEN action = 'A'
THEN 1
ELSE 0
END) AS action_a
,sum(CASE
WHEN action = 'B'
THEN 1
ELSE 0
END) AS action_b
FROM logs l
GROUP BY user_id
,session_id
,search_query
)
SELECT search_query
,(sum(action_a - action_b) / sum(action_a)) * 100 AS miss_percentage
FROM summary
GROUP BY search_query;
如果问题是关于PostgreSQL的,为什么要使用MSSQL解决方案呢?SQL在不同引擎之间非常兼容。这个答案有助于跨系统使用SQL的概念。我只能在MS-SQL上测试解决方案。我对这一点的否决票不太满意……SQL是一个标准,MSSQL以偏离它而闻名,远远超过PostgreSQL。后者没有用于指定目的的isNull函数,但使用coalesce。无论是在PostgreSQL还是MSSQL中运行,您的代码中都有错误。否决票是因为回答不充分。对不起,以前忘了提这个。我正在amazon红移表中运行此查询。我得到以下错误。执行SQL命令时出错:SELECT l1.search\U query,countcase当不存在时从日志l2中选择1,其中l1.user\U id=l。。。错误:由于内部错误[SQL State=XX000],不支持这种类型的相关子查询模式