简体   繁体   English

将表连接到SQL Server中的两个一对多关系表

[英]Joining a table to two one-to-many relationship tables in SQL Server

Happy Friday folks, 周五快乐的人,

I'm trying to write an SSRS report displaying data from three (actually about 12, but only three relevant) tables that have akward relationships and the SQL query behind the data is proving difficult. 我正在尝试编写一份SSRS报告,显示来自三个(实际上大约有12个,但只有三个相关)表的数据,这些表具有不正常的关系,并且数据背后的SQL查询证明是困难的。

There are three entities involved - a Purchase Order, a Sales Order, and a Delivery. 涉及三个实体 - 采购订单,销售订单和交货。 The problem is the a Purchase Order can have many sales orders, and also many deliveries which are NOT linked to the sales orders...that would be too easy. 问题在于采购订单可能有许多销售订单,还有许多与销售订单无关的交货......这太简单了。

Both the Sales Order and Delivery tables can be linked to the Purchase Order table by foreign keys and an intermediate table each. 销售订单和交货表都可以通过外键和每个中间表链接到采购订单表。

I need to basically list Purchase Orders, a list of sales orders and a list of deliveries next to them, with NULLs for any fields that aren't valid so that'll give the required output in SSRS/when read by a human, ie, for a purchase order with 2 sales orders and 4 delivery dates; 我需要基本上列出采购订单,销售订单列表和它们旁边的交货清单,对于任何无效的字段都是NULL,这样当人类读取时,它将在SSRS /中提供所需的输出,即,对于包含2个销售订单和4个交货日期的采购订单;

PO    SO      Delivery
1234  ABC     05/10
1234  DEF     09/10
1234  NULL    10/12
1234  NULL    14/12

The above (when grouped by PO) will tell the users there are two sales orders and four (unlinked) delivery dates. 以上(按PO分组)将告诉用户有两个销售订单和四个(未链接的)交货日期。

Likewise if there are more SOs than deliveries, we need NULLs in the Delivery column; 同样,如果有多个SO而不是交付,我们在交付列中需要NULL;

PO    SO      Delivery
1234  ABC     03/08
1234  DEF     NULL
1234  GHI     NULL
1234  JKL     NULL  

Above would be the case with 4 SOs and one delivery date. 以上是4个SO和一个交付日期的情况。

Using Left Outer joins alone gives too much duplication - in this case 8 rows, as it gives 4 delivery dates for each match on the sales order; 单独使用左外连接会产生太多重复 - 在这种情况下为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

It's fine that the PO column is duplicated as SSRS can visually group that - but the SO/Delivery fields can't be allowed to duplicate as this can't be got rid of in the report - if I group the column in SSRS by SO then it still spits out 4 delivery dates for each one. 由于SSRS可以在视觉上对其进行分组,因此可以将PO列重复进行复制 - 但是SO / Delivery字段不能被复制,因为这在报告中无法解决 - 如果我将SSRS中的列分组为SO那么它仍然会为每个交付日期吐出4个交付日期。

The only situation our query works nice is when there is just one SO per PO. 我们的查询工作得很好的唯一情况是每个PO只有一个SO。 In that case the single PO and SO numbers are duplicated together for x deliveries and can both be neatly grouped in SSRS. 在这种情况下,单个PO和SO号码一起复制用于x交付,并且可以在SSRS中整齐地分组。 Unfortunately this is a rare occurence in the data. 不幸的是,这是数据中罕见的情况。

I've thought of trying to use some sort of windowing function or CROSS APPLY but both fall down as they will repeat for every PO number listed and end up spitting out too much data. 我曾经想过尝试使用某种窗口函数或CROSS APPLY但是它们都会掉下来,因为它们将针对列出的每个PO编号重复,最终会吐出过多的数据。

At the point of thinking this just isn't set-based enough to be doable in SQL, I know the data is horrible.. 在思考的时候,这只是基于设置不足以在SQL中可行,我知道数据很可怕..

Any help much appreciated. 任何帮助非常感谢。

EDIT - basical sqlfiddle link to the table schemas. 编辑 - 表格模式的基本sqlfiddle链接。 Omitted many columns which aren't relevant. 省略了许多不相关的列。 http://sqlfiddle.com/#!2/5ba16 http://sqlfiddle.com/#!2/5ba16

Example data... 示例数据......

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

If you assign row numbers to the elements in salesorders and deliveries, you can link on that. 如果您将行号分配给销售人员和交货中的元素,则可以链接该行号。

Something like this 像这样的东西

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          

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM