在 MySQL (PartitionQualify(?
Posted
技术标签:
【中文标题】在 MySQL (PartitionQualify(?【英文标题】:Mixing HAVING with CASE OR Analytic functions in MySQL (PartitionQualify(? 【发布时间】:2014-11-03 19:05:41 【问题描述】:我有一个 SELECT 查询,它返回一些像这样的字段:
Date | Campaign_Name | Type | Count_People
Oct | Cats | 1 | 500
Oct | Cats | 2 | 50
Oct | Dogs | 1 | 80
Oct | Dogs | 2 | 50
查询使用聚合,我只想包含当 Type = 1 时的结果,然后确保相应的 Count_People 大于 99。
使用示例表,我希望返回两行:Cats。如果 Dogs 是 1 类,则将其排除在外,因为它低于 100,在这种情况下,Dogs = 2 也应排除在外。
换句话说,如果 type = 1 小于 100 则删除相应活动名称的所有记录。
我开始尝试这个:
HAVING CASE WHEN type = 1 THEN COUNT(DISTINCT Count_People) > 99 END
我在今年早些时候使用过 Teradata,记得曾经处理过一个使用分析函数“Qualify PartitionBy”的查询。我怀疑这些方面的东西是我需要的?我需要在运行查询之前将排除基于聚合?
我将如何在 mysql 中执行此操作?我说得有道理吗?
【问题讨论】:
MySQL 没有窗口函数(又名“分析函数”)。所以你需要找到一个不同的解决方案 【参考方案1】:既然我理解了这个问题,我认为您最好的选择是使用子查询来确定 type=1 的哪些日期/活动组合的 count_people 大于 99。
SELECT
<table>.date,
<table>.campaign_name,
<table>.type,
count(distinct count_people) as count_people
FROM
(
SELECT
date,
campaign_name
FROM
<table>
WHERE type=1
HAVING count(distinct count_people) > 99
GROUP BY 1,2
) type1
LEFT OUTER JOIN <table> ON
type1.campaign_name = <table>.campaign_name AND
type1.date = <table>.date
WHERE <table>.type IN (1,2)
GROUP BY 1,2,3
此处的子查询仅在 type=1 且 count_people 大于 99 时返回活动/日期组合。它使用 LEFT JOIN 返回到 以确保只有那些活动/日期组合才能进入结果集。
主查询上的 WHERE 仅将结果保留为类型 1 和 2,您说这已经是一个过滤器(尽管问题中没有提到,但在对先前答案的评论中有所说明)。
【讨论】:
【参考方案2】:根据@JNevill 回答的您的 cmets,我认为您别无选择,只能使用子选择来预过滤您正在处理的记录集,因为使用 HAVING
只会将您限制在当前正在评估的记录 - 无法以这种方式与集合中的先前或后续记录进行比较。
所以看看这样的东西:
SELECT
full_data.date AS date,
full_data.campaign_name AS campaign_name,
full_data.type AS type,
COUNT(full_data.people) AS people_count
FROM
(
SELECT
date,
campaign_name,
type,
COUNT(people) AS people_count
FROM table
WHERE type IN (1,2)
GROUP BY date, campaign_name, type
) AS full_data
LEFT JOIN
(
SELECT
date,
campaign_name,
COUNT(people) AS people_count
FROM table
WHERE type = 1
GROUP BY date, campaign_name
HAVING people_count < 100
) AS filter
ON
full_data.date = filter.date
AND full_data.campaign_name = filter.campaign_name
WHERE
filter.date IS NULL
AND filter.campaign_name IS NULL
第一个子选择基本上是您当前的查询,没有尝试使用HAVING
过滤掉结果。第二个子选择用于查找具有people_count
> 100 的所有日期/广告系列名称组合,并将它们用作针对完整数据集的过滤器。
【讨论】:
抱歉,在输入此内容时没有看到@JNevill 的答案。这是相同的基本概念,只是语义略有不同。我使用 NULL 过滤器而不是正过滤器。以上是关于在 MySQL (PartitionQualify(?的主要内容,如果未能解决你的问题,请参考以下文章