在 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(?的主要内容,如果未能解决你的问题,请参考以下文章

如何在电脑内重新安装mysql数据库

MySQL 安装与启动

windows下的mysql配置文件在哪

如何在mysql中显示中文???

mysql日志没在控制台打印log

怎么确定自己的mysql安装在哪