Sql WITH子句中的语法错误,正在检查查询

Sql WITH子句中的语法错误,正在检查查询,sql,subquery,common-table-expression,window-functions,Sql,Subquery,Common Table Expression,Window Functions,我有以下sql问题需要解决: 表:事件,包含以下列: 列名:business\u id和类型:int 列名:事件类型和类型:varchar 列名:事件和类型:int (业务\ id,事件\类型)是此表的主键。 表中的每一行都记录了某些类型的事件在某些业务中发生多次的信息 编写SQL查询以查找所有活动业务,其中活动业务是具有多个事件类型的业务,其发生次数大于所有业务中该事件类型的平均发生次数 查询结果格式如下例所示: 事件表: {“headers”:{“Events”:[“business_id”

我有以下sql问题需要解决: 表:事件,包含以下列: 列名:business\u id和类型:int 列名:事件类型和类型:varchar 列名:事件和类型:int

(业务\ id,事件\类型)是此表的主键。 表中的每一行都记录了某些类型的事件在某些业务中发生多次的信息

编写SQL查询以查找所有活动业务,其中活动业务是具有多个事件类型的业务,其发生次数大于所有业务中该事件类型的平均发生次数

查询结果格式如下例所示:

事件表: {“headers”:{“Events”:[“business_id”,“event_type”,“occurrences”]},行:{“Events”:[[1,“评论”,7],[3,“评论”,3],[1,“ads”,11],[2,“ads”,7],[3,“ads”,6],[1,“页面浏览”,3],[2,“页面浏览”,12]}

上面的结果表将有一个名为business_id的列,其中一行包含1

说明:“评论”、“广告”和“页面浏览量”的平均值分别为(7+3)/2=5、(11+7+6)/3=8、(3+12)/2=7.5。 只有id为1的业务有7个“评论”活动(超过5个)和11个“广告”活动(超过8个),因此它是唯一活跃的业务

我编写了以下查询:

WITH firstTable (event_type,avg_o) as (SELECT Events.event_type, avg(occurences) as avg_o
FROM Events
GROUP BY event_type)

WITH secondTable (business_id,event_type,avg2,g) as (SELECT Events.business_id, Events.event_type,firstTable.avg_o,
CASE
    WHEN Events.occurences>firstTable.avg_o THEN 1
    ELSE 0
END as g
FROM Events
JOIN firstTable
ON Events.event_type = firstTable.event_type)

WITH thirdTable as (SELECT business_id, sum(g) as g2
FROM secondTable
GROUP BY business_id)

SELECT business_id
FROM thirdTable
WHERE g2>1;
问题:

  • 我的查询中似乎有语法错误。你能帮我确定它们是什么以及如何纠正它们吗
  • 我的查询对解决问题有用吗
  • 我相信有一种使用窗口函数的解决方案。从性能角度来看,这比我使用CTE的方法更好吗?正如您在上面看到的那样
  • 非常感谢你的帮助。非常感谢


    Aly

    这里有一个使用窗口函数和聚合的选项:

    select business_id
    from (
        select e.*,
            avg(occurrences) over(partition by event_type) avg_occurences
        from events e
    ) e
    where occurences > avg_occurences
    group by business_id
    having count(*) > 1
    

    在子查询中,窗口函数计算具有相同
    事件类型的行上发生的
    事件的平均值。然后,外部查询对值大于平均值的行进行筛选,按业务聚合,并保留多行的组。

    受GMB优秀答案的启发,下面是一个更简单的CTE答案:

    WITH 
    firstTable (event_type,avg_o) as (SELECT Events.event_type, avg(occurences) as avg_o
    FROM Events
    GROUP BY Events.event_type)
    
    SELECT Events.business_id
    FROM Events
    JOIN firstTable
    ON Events.event_type=firstTable.event_type
    WHERE occurences>avg_o
    GROUP BY Events.business_id
    Having count(*)>1;
    
    还有另一个更简单的子查询答案:

    SELECT Events.business_id
    FROM Events
    JOIN (SELECT Events.event_type, avg(occurences) as avg_o
    FROM Events
    GROUP BY Events.event_type) as firstTable
    ON Events.event_type=firstTable.event_type
    WHERE occurences>avg_o
    GROUP BY Events.business_id
    Having count(*)>1;
    

    此外,我在问题本身的第一个答案中的主要语法错误是,就像提到了没有名字的马一样,即使有多个CTE,也应该只有1个。

    我删除了冲突的数据库标记。请仅为实际使用的数据库添加标记。如果您遇到错误,请回答您的问题并添加您收到的完整错误消息(您的问题,请不要在注释中添加其他信息)。带
    关键字的
    仅需要一次。要组合多个CTE,只需用逗号分隔它们:非常感谢。你的评论解决了我的语法错误,也就是说,当我使用关键字时,它工作得很好,并且为所有测试用例提供了正确的解决方案,所以我猜它是正确的。剩下的唯一一个问题(作为对“GMB”答案的评论,我在下面提出的是比较我的CTE解决方案与他的窗口函数1的性能。非常感谢!非常感谢。这很有效。我的解决方案在纠正语法错误后也有效(我只需要使用一次,作为“没有名字的a_horse_”).现在,问题是:您的窗口函数解决方案在性能方面是否比我使用CTE的方法更好,或者我的方法更好,或者它们是相同的?@Aly:我希望窗口函数解决方案更高效,因为它只扫描表一次(而不是使用CTE多次扫描)。写起来也比较短……但您需要根据实际数据集进行评估。受您答案的启发,我能够做一个更简单的1 CTE答案和另一个1子查询答案(请参见下面的答案)。假设它只有1 CTE(或1子查询),是否与窗口函数解决方案相同?@Aly:这仍然是两个表扫描和一个联接。@Aly…这个答案比你的答案简单,你应该接受它。