【问题标题】:Query all columns of table1 left join and count of the table2查询table1的所有列left join和table2的count
【发布时间】:2019-05-03 10:22:56
【问题描述】:

我无法让这个查询工作:

不起作用

select 
    Region.*, count(secteur.*) count 
from  
    Region 
left join 
    secteur on secteur.region_id = Region.id

我找到的解决方案是这样,但有没有更好的使用连接的解决方案,或者这不会影响性能,因为我有一个非常大的数据集,大约 500K 行

工作但担心性能问题

select 
    Region.*,
    (select count(*) 
     from Secteur 
     where Secteur.Region_id = region.id) count 
from  
    Region 

【问题讨论】:

  • 你为什么不用COUNT(Single_Colunm)
  • @PrashantPimpale 因为it makes no difference.
  • @RuudHelderman 是的,所有情况都相同吗?因为有一个查询需要 1 分 13 秒才能执行,我使用的是 COUNT(*),但是一旦我更改为 COUNT(_id) 这是 int 值,现在它需要 10 到 15 秒才能执行!
  • @PrashantPimpale 用冷缓存还是热缓存测试?指数统计数据是最新的吗? _id 是否持有空值?除了持续时间,你是否测量了 I/O 和 CPU?您是否比较了查询计划?什么版本和版本的 SQL Server?我愿意认真对待您的主张,但如果没有MCVE,则该主张毫无意义。

标签: sql sql-server select sql-server-2012 count


【解决方案1】:

我建议:

select region.*, count(secteur.region_id) as count
from region left join secteur on region.id = secteur.region_id
group by region.id, region.field2, region.field3....

请注意,count(table.field)忽略空值,而 count(*) 将包含它们。


或者,在子查询上左连接并使用coalesce 来避免空值:

select region.*, coalesce(t.c, 0) as count
from region left join 
(select region_id, count(*) as c from secteur group by region_id) t on region.id = t.region_id

【讨论】:

  • 在 * 附近返回不正确的语法(按行分组)??!!
  • 抱歉,您需要列出 region 中包含的字段,并按每个字段进行分组。
【解决方案2】:

我将加入 region 的聚合查询 secteur

SELECT    r.*, COALESCE(s.cnt, 0)
FROM      region r
LEFT JOIN (SELECT   region_id, COUNT(*) AS cnt
           FROM     secteur
           GROUP BY region_id) s ON s.region_id = r.id

【讨论】:

  • 就性能而言,我认为它比我的工作查询更好??!!
  • @seddik 但这不是使用LEFT JOIN
  • 我已经添加了一个左连接,这是我认为最方便的解决方案
【解决方案3】:

我会用这个查询:

select r.*,
       (select count(*) 
        from Secteur s
        where s.Region_id = r.id
      ) as num_secteurs 
from Region r;

然后通过在Secteur(region_id)上添加索引来修复性能问题:

create index idx_secteur_region on secteur(region_id);

【讨论】:

    【解决方案4】:

    你犯了两个错误

    • 首先:您尝试仅在一个(我的意思是第二个)表中计算 COUNT()。这是行不通的,因为 COUNT() 与任何聚合函数一样,仅针对整组行进行计算,而不只是针对集合的任何部分(不仅针对一个或一个其他连接表)。
      在您的第一个查询中,您可以仅将 secteur. * 替换为星号,例如 Region.region_id, count(*) AS count,并且不要忘记在 GROUP BY 步骤中添加 Region.region_id。
    • 第二:您不仅在查询中定义了聚合函数,还定义了其他字段:select Region.*,但您没有在GROUP BY 步骤中定义它们。您需要将您在SELECT 步骤中定义的所有列添加到GROUP BY 语句,但不要对它们应用聚合函数。
    • 追加:不,GROUP BY Region.* 不起作用,您应该在GROUP BY 步骤中按实际名称定义列。

    所以,这个的正确形式看起来像一个

    SELECT 
        Region.col1
        ,Region.col2,
        , count(*) count 
    from  Region 
    left join 
        secteur on secteur.region_id = Region.id
    GROUP BY Region.col1, Region.col2
    

    或者,如果您不想键入每个列的名称,请使用 窗口查询

    SELECT
        Region.*,
        , count( * ) OVER (PARTITION BY region_id) AS count 
    from  Region 
    left join 
        secteur on secteur.region_id = Region.id
    

    【讨论】:

      猜你喜欢
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多