子查询有问题

时间:2021-04-29 05:30:48

标签: sql subquery derived-table

这里是问题的问题:“FR3.Q7:10 月 15 日之后发生的所有视图(所有列),由 Kindle 设备,由 Yelp 托管,来自拥有 10 个以上客户的城市。同时添加名称每个视图的客户(作为第一列)和客户的城市(作为第二列)“

我在我的代码中做到了这一点

SELECT c.[Name]
      ,c.City
      ,v.ViewID
      ,v.ViewDate
      ,(v.ID)
      ,v.Device
      ,v.Browser
      ,v.Host
FROM [View] v JOIN Client c ON v.ID = c.ClientID
WHERE v.ViewDate >= '2019-10-16' AND v.Device LIKE '%kindle' AND v.Host LIKE '%yelp'
GROUP BY c.[Name],c.City,v.ViewID,v.ViewDate,v.ID,v.Device,v.Browser,v.Host 

我得到的结果非常接近答案,但是结果中没有“至少有 10 个客户的城市”过滤器。无论我如何尝试将此过滤器放入上面的代码中,它都会返回一个空白表。

下面的这段代码成功地分别拉出了至少有 10 个客户端的 Cities,但是我不知道如何将此代码放入上面的代码行中。我试过子查询和派生表,但没有任何效果。任何帮助将不胜感激

SELECT City 
FROM Client
GROUP BY City
HAVING COUNT(ClientID) > 10

2 个答案:

答案 0 :(得分:0)

将您的 HAVING 查询放在那里并将其作为子查询加入

SELECT c.[Name]
      ,c.City
      ,v.ViewID
      ,v.ViewDate
      ,(v.ID)
      ,v.Device
      ,v.Browser
      ,v.Host
FROM [View] v JOIN Client c ON v.ID = c.ClientID

JOIN(SELECT City 
FROM Client
GROUP BY City
HAVING COUNT(ClientID) > 10) tenplus 
ON c.City = tenplus.city


WHERE v.ViewDate >= '2019-10-16' AND v.Device LIKE '%kindle' AND v.Host LIKE '%yelp'
GROUP BY c.[Name],c.City,v.ViewID,v.ViewDate,v.ID,v.Device,v.Browser,v.Host 

我故意把格式弄得一团糟,以概述它是如何插入的,但应该整理一下..

基本上,子查询形成一个城市列表,使用内连接将其连接将导致不符合条件的城市被丢弃

顺便说一下,您可能不需要外部查询中的 GroupBy;它对所有内容进行分组,并且选择列表中没有聚合。如果您使用它来压缩重复项,请检查是否存在导致笛卡尔爆炸的连接错误(可能视图具有选定列的多个相同记录;旨在使用 where 子句删除重复项,而不是连接它们,然后再进行去重)

评论中提到的其他方式:

SELECT c.[Name]
      ,c.City
      ,v.ViewID
      ,v.ViewDate
      ,(v.ID)
      ,v.Device
      ,v.Browser
      ,v.Host
FROM [View] v JOIN Client c ON v.ID = c.ClientID
WHERE v.ViewDate >= '2019-10-16' AND v.Device LIKE '%kindle' AND v.Host LIKE '%yelp'

AND c.city IN(SELECT City 
FROM Client
GROUP BY City
HAVING COUNT(ClientID) > 10)

GROUP BY c.[Name],c.City,v.ViewID,v.ViewDate,v.ID,v.Device,v.Browser,v.Host 
SELECT c.[Name]
      ,c.City
      ,v.ViewID
      ,v.ViewDate
      ,(v.ID)
      ,v.Device
      ,v.Browser
      ,v.Host
FROM [View] v JOIN Client c ON v.ID = c.ClientID
WHERE v.ViewDate >= '2019-10-16' AND v.Device LIKE '%kindle' AND v.Host LIKE '%yelp'

AND EXISTS(SELECT null 
FROM Client x
WHERE x.city = c.city
GROUP BY City
HAVING COUNT(ClientID) > 10)

GROUP BY c.[Name],c.City,v.ViewID,v.ViewDate,v.ID,v.Device,v.Browser,v.Host 

这些天它们可能都以相同的方式工作

答案 1 :(得分:0)

使用窗口函数统计一个城市的客户:

SELECT c.[Name], c.City, v.ViewID, v.ViewDate, v.ID,
       v.Device, v.Browser, v.Host
FROM [View] v JOIN
     (SELECT c.*, COUNT(*) OVER (PARTITION BY city) as cnt_city
      FROM Client c 
     ) c
     ON v.ID = c.ClientID
WHERE v.ViewDate >= '2019-10-16' AND
      v.Device LIKE '%kindle' AND
      v.Host LIKE '%yelp' AND
      c.cnt_city >= 10
GROUP BY c.[Name], c.City, v.ViewID, v.ViewDate, v.ID, v.Device, v.Browser, v.Host ;

注意:我想知道您是否真的需要 GROUP BY。这是一个相当昂贵的操作。 JOIN 是否创建了重复项?或者他们在视图中?还是两者兼而有之?

您没有提供数据的解释。您可能想就示例数据和所需结果提出另一个问题。