周五快乐的人们,
我正在尝试编写一份SSRS报告,显示三个(实际上大约有12个,但只有三个相关)表的数据,这些表具有不正常的关系,并且数据背后的SQL查询很难实现。
涉及三个实体 - 采购订单,销售订单和交货。问题是采购订单可能有许多销售订单,还有许多与销售订单无关的交货......这太容易了。
销售订单和交货表都可以通过外键和每个中间表链接到采购订单表。
我需要基本上列出采购订单,销售订单清单和它们旁边的交货清单,对于任何无效的字段都使用NULL,以便在由SSRS读取时提供所需的输出人,即具有2个销售订单和4个交货日期的采购订单;
PO SO Delivery
1234 ABC 05/10
1234 DEF 09/10
1234 NULL 10/12
1234 NULL 14/12
以上(按PO分组)将告诉用户有两个销售订单和四个(未链接的)交货日期。
同样,如果有更多的SO而不是交付,我们在交付列中需要NULL;
PO SO Delivery
1234 ABC 03/08
1234 DEF NULL
1234 GHI NULL
1234 JKL NULL
以上是4个SO和一个交付日期的情况。
单独使用左外连接会产生太多重复 - 在这种情况下为8行,因为它为销售订单上的每个匹配提供了4个交付日期;
PO SO Delivery
1234 ABC 05/10
1234 ABC 09/10
1234 ABC 10/12
1234 ABC 14/12
1234 DEF 05/10
1234 DEF 09/10
1234 DEF 10/12
1234 DEF 14/12
PO列很复杂,因为SSRS可以直观地对其进行分组 - 但是SO / Delivery字段不能被复制,因为这在报告中无法解决 - 如果我将列分组SOS的SSRS然后它仍然会为每一个提供4个交付日期。
我们的查询工作得很好的唯一情况是每个PO只有一个SO。在这种情况下,单个PO和SO号码一起复制用于x交付,并且可以在SSRS中整齐地分组。不幸的是,这是数据中罕见的情况。
我曾想过尝试使用某种窗口功能或CROSS APPLY,但两者都会掉线,因为它们会针对列出的每个PO编号重复,最终会吐出太多数据。
在考虑这个问题时,基于设置不足以在SQL中可行,我知道数据很糟糕。
任何帮助非常感谢。
EDIT - 表格模式的基本sqlfiddle链接。省略了许多不相关的列。 http://sqlfiddle.com/#!2/5ba16
示例数据......
Purchase Order
PO_Number Style
1001 Black work boots
1002 Green hat
1006 Red Scarf
Sales Order
Sales_order_number PO_number Qty Retailer
A100-21 1001 15 Walmart
A100-22 1001 29 Walmart
A200-31 1006 1000 Asda
Delivery
Delivery_ID Delivery_Date PO_number
1543285 10/05/2014 1001
1543286 12/05/2014 1001
1543287 17/05/2014 1001
1543288 21/05/2014 1002
答案 0 :(得分:1)
如果您为销售订单和交货中的元素分配行号,则可以链接该行号。
像这样的东西
declare @salesorders table (po int, so varchar(10))
declare @deliveries table (po int, delivery date)
declare @purchaseorders table (po int)
insert @purchaseorders values (123),(456)
insert @salesorders values (123,'a'),(123,'b'),(456,'c')
insert @deliveries values (123,'2014-1-1'),(456,'2014-2-1'),(456,'2014-2-1')
select *
from
(
select numbers.number, p.po, so.so, d.delivery from @purchaseorders p
cross join (Select number from master..spt_values where type='p') numbers
left join (select *,ROW_NUMBER() over (partition by po order by so) sor from @salesorders ) so
on p.po = so.po and numbers.number = so.sor
left join (select * , ROW_NUMBER() over (partition by po order by delivery) dor from @deliveries) d
on p.po = d.po and numbers.number = d.dor
) v
where so is not null or delivery is not null
order by po,number