【问题标题】:SQL Query - Grouping/Aggregating Across multiple TablesSQL 查询 - 跨多个表分组/聚合
【发布时间】:2016-11-14 00:00:24
【问题描述】:
select D.[Date], E.emp_name, E.emp_jde, count(C.[agent_no]) calls, count(S.[EMPJDENUM]) sales
from
(select cast([start_date] as date) dte, [agent_no]
from call_table
where [skill_name] like '%5700 sales l%'
and [Agent_Time] != '0'
) C
full outer join
(select [AC#DTE_dt], [EMPJDENUM]
from sales_table
where [ICGCD2] in ('LAWN', 'HORT')
and [CHANNEL]= 'INQ'
and [ITMQTY]>3
) S on c.dte=s.[AC#DTE_dt]
right join
(select [Date]
from Date_table
) D on c.dte=d.[Date] or s.[AC#DTE_dt]=d.[Date]
right join
(select [emp_name], [emp_jde], [agent_no]
from Employee_table
) E on C.[agent_no]=E.agent_no and S.[EMPJDENUM]=E.emp_jde
group by D.[Date], E.emp_name, E.emp_jde

日期表 -

注意:并非所有日期都有电话和销售。

附加表 -

需要完成的事情——

1) 通过加入 call 表(在 agent_no 上)和 sales(在 JDE 上)表来加入和聚合员工的 call 和 sales

2) 由于并非所有日期都包括电话和销售 - 使用日期维度表来确保所有日期都被表示

想要的结果应该是这样的 -

我写的查询执行了 - 花了很长时间我最终取消了查询。

任何帮助将不胜感激。

【问题讨论】:

  • 每个表中大约有多少行?
  • 每年调用表大约有 800k 数据,sales 表大约有 400k 数据。
  • 能否提供估计的执行计划请brentozar.com/pastetheplan

标签: sql-server join subquery aggregate


【解决方案1】:

没有看到查询计划,这有点棘手,但这里有几个可能会提高性能的建议:

  1. 删除where [skill_name] like '5700 sales l%' 中的前导通配符
  2. group by 放入子查询中

我这里有一个实现这两个的例子。 (请注意,我进行了一些重新格式化只是为了尝试了解您的查询在做什么。)

select D.[Date], E.emp_name, E.emp_jde, C.Calls, S.Sales
  from Date_table As D
  Left Join (
    select cast([start_date] as date) As CallDate, [agent_no], Count(*) As Calls
      from call_table
      where [skill_name] like '5700 sales l%'
        and [Agent_Time] != '0'
      Group By Cast([start_date] As date), [agent_no]) As C On D.[Date] = C.CallDate
  Left Join (
    select [AC#DTE_dt] As SaleDate, [EMPJDENUM], Count(*) As Sales
      from sales_table
      where [ICGCD2] in ('LAWN', 'HORT')
        and [CHANNEL]= 'INQ'
        and [ITMQTY]>3
      Group By [AC#DTE_dt], [EMPJDENUM]) As S on D.[Date] = s.SaleDate
  right join Employee_table As E 
    on C.[agent_no]=E.agent_no 
    and S.[EMPJDENUM]=E.emp_jde;

编辑

为了为每个可能的日期和员工组合获取一行,您需要对日期表和员工表进行交叉连接。

select D.[Date], E.emp_name, E.emp_jde, C.Calls, S.Sales
  from Date_table As D,
      Employee_table as E
  Left Join (
    select cast([start_date] as date) As CallDate, [agent_no], Count(*) As Calls
      from call_table
      where [skill_name] like '5700 sales l%'
        and [Agent_Time] != '0'
      Group By Cast([start_date] As date), [agent_no]) As C 
    On D.[Date] = C.CallDate
    And E.agent_no = C.agent_no
  Left Join (
    select [AC#DTE_dt] As SaleDate, [EMPJDENUM], Count(*) As Sales
      from sales_table
      where [ICGCD2] in ('LAWN', 'HORT')
        and [CHANNEL]= 'INQ'
        and [ITMQTY]>3
      Group By [AC#DTE_dt], [EMPJDENUM]) As S 
    on D.[Date] = s.SaleDate
    and E.emp_jde = S.[EMPJDENUM];

【讨论】:

  • 这非常接近 - 但是,如果有人在某一天有一个没有销售的电话或没有销售的电话,就会将他们排除在结果之外。
  • 而且这个查询运行效率很高。
  • @user3067478 我做了一些调整,即使没有销售或电话也应该返回行
  • 当我尝试调整后的查询时,它告诉我 D.Date 无法绑定。一旦我从员工表中删除了附加项,我就不再收到该错误。
  • @user3067478 这个答案似乎对你有帮助,因为你在另一个问题stackoverflow.com/questions/40642404/… 中引用了它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多