SQL多对多分组成一行

时间:2014-01-10 22:31:05

标签: sql sql-server join group-by

我确实使用了搜索,但是几个结果似乎没有回答我的具体问题(或者我的sql技能不足以将答案应用到我的场景中)

我有桌子需要加入。上下文是交付业务。一个表包含交付轮计划。我在此表中需要的是客户注册每周交货的日期。这与帐号有关。

另一个表包含帐号,交货日期实例等

我要做的是提取过去6周内每个帐号的平均交付次数。但仅适用于开始日期为6到10周之前的帐户。

我使用的代码似乎带回了正确的日期范围,但是,我需要每个帐号一行,并且在6周的时间内需要一个平均交付次数。我正在使用的代码没有正确执行此操作。

非常感谢任何帮助。

THANKYOU

select mov.AccountNumber,
sch.contractStart,
mov.TypeOfMovement,
mov.Outlet,
mov.RoundName,
mov.VehicleType,
avg(mov.NumberofItems)


FROM [round_movements]mov  
left outer join [schedule]sch on sch.AccountNumber=
mov.AccountNumber                          
where mov.outlet='County'
and DATEDIFF(week, sch.ContractStart,GETDATE()) in(10,9,8,7,6)
and DATEDIFF(week, mov.RoundDate,GETDATE()) in (6,5,4,3,2,1,0)

group by 
mov.AccountNumber,
mov.RoundName,
sch.contractStart,
mov.TypeOfMovement,
mov.Outlet,
mov.VehicleType,
mov.NumberofItems
order by mov.AccountNumber

以上代码的结果:

 ════════════════════════════════════════════════════════════════════════════════════════╗
║ AccountNumber   contractStart  Outlet   RoundName       VehicleType   Avg  No of Items ║
╠════════════════════════════════════════════════════════════════════════════════════════╣
║ 4000461         27/11/2013    town1     E4 (Wednesday)  sprinter       1               ║
           ║
║ 6382401         29/10/2013    town2     E1 (Thursday)   sprinter       2               ║
║ 6382401         29/10/2013    town2     E1 (Thursday)   sprinter       2               ║
╚════════════════════════════════════════════════════════════════════════════════════════╝

预期结果:

╔═════════════════════════════════════════════════════════════════════════════════════╗
║ AccountNumber   contractStart   Outlet  RoundName      VehicleType Avg No Items     ║
╠═════════════════════════════════════════════════════════════════════════════════════╣
║ 4000461         27/11/2013      town 1  E4 (Wednesday)  sprinter    1               ║
║ 6382401         29/10/2013      town2   E1 (Thursday)   sprinter    2               ║
║            ║
╚═════════════════════════════════════════════════════════════════════════════════════╝ 

以下建议更改后的结果为Rs:

╔═════════════════════════════════════════════════════════════════════════════════════╗
║ AccountNumber   contractStart   Outlet  RoundName      VehicleType Avg No Items     ║
╠═════════════════════════════════════════════════════════════════════════════════════╣
║   
  4000461   27/11/2013  Bristol E4 (Wednesday)  RCV 1
  6382401   29/10/2013  Bristol E1 (Thursday)   RCV 2
  6382401   29/10/2013  Bristol E1 (Thursday)   RCV 2

          ║
╚═════════════════════════════════════════════════════════════════════════════════════╝ 

3 个答案:

答案 0 :(得分:0)

尝试此操作,从列列表中删除mov.NumberofItems

select mov.AccountNumber,
sch.contractStart,
mov.TypeOfMovement,
mov.Outlet,
mov.RoundName,
mov.VehicleType,
avg(mov.NumberofItems)


FROM [round_movements]mov  
left outer join [schedule]sch on sch.AccountNumber=
mov.AccountNumber                          
where mov.outlet='County'
and DATEDIFF(week, sch.ContractStart,GETDATE()) in(10,9,8,7,6)
and DATEDIFF(week, mov.RoundDate,GETDATE()) in (6,5,4,3,2,1,0)

group by 
mov.AccountNumber,
mov.RoundName,
sch.contractStart,
mov.TypeOfMovement,
mov.Outlet,
mov.VehicleType
order by mov.AccountNumber

答案 1 :(得分:0)

我可以看到一些阻止你获得预期结果的东西。

  1. 您不需要组中的mov.NumberofItems,因为您正在对它进行平均。
  2. 您需要使用MIN函数来给出第一个合约开始日期,例如min(sch.contractStart),然后您不需要在group by中使用sch.contractStart。
  3. 这可以为您提供您期望的结果。

    所以你的查询会是这样的。

    select 
      mov.AccountNumber,
      min(sch.contractStart),
      mov.TypeOfMovement,
      mov.Outlet,
      mov.RoundName,
      mov.VehicleType,
      avg(mov.NumberofItems)
    FROM 
      [round_movements]mov  
      left outer join [schedule]sch on sch.AccountNumber=mov.AccountNumber                          
    where 
      mov.outlet='County'
      and DATEDIFF(week, sch.ContractStart,GETDATE()) in(10,9,8,7,6)
      and DATEDIFF(week, mov.RoundDate,GETDATE()) in (6,5,4,3,2,1,0)
    group by 
      mov.AccountNumber,
      mov.RoundName,
      mov.TypeOfMovement,
      mov.Outlet,
      mov.VehicleType,
      mov.NumberofItems
    order by 
      mov.AccountNumber
    

答案 2 :(得分:0)

附加其他人所说的话:

您获得多个结果的原因是sch.contractStart对于2个记录的2个帐号是不同的 您可以做的是将sch.contractStart包裹在MAX()中并将其从GROUP BY中删除。这将为您提供特定帐号的最新合约开始日期,我认为从逻辑角度来看这是合理的。

编辑 - OP的问题编辑后
我可以看到更新的结果,有2个完全相同的记录。 你可以将整个事物包装成SELECT DISTINCT来消除它。但这不是正确的方式。

实际上,如果所有内容都在group by或aggregate函数中,我看不出任何重复记录的原因。 您是否从mov.NumberofItems移除了GROUP BY