kin*_*nix 5 sql sql-server one-to-many flatten sql-server-2008
好的,我有一个输入订单的系统,每个订单都可以附加任意数量的债券,工作和项目编号.该OrderDetails表包含一个orderID用于转到OrderNumbers表并获取所有附加"数字"到此订单,然后根据在numType那里找到的列,它进入三个表之一(bond,job,project)并检索实际数字为用户显示和打印.
这意味着,如果该订单附加了3个项目编号,则尝试查询订单以搜索某个项目编号可以为同一订单返回3行.
我希望能够返回我的查询结果,只有1行的订单,以及包含所有3个分隔形式的项目的列,这可能吗?
这是我当前的查询,当订单附加多个相同类型的数字时,每个订单返回多行...
SELECT
ISNULL(b.Descr,'') as Bond, ISNULL(PO.Description,'') as PO,
ISNULL(j.Descr,'') as Job, ISNULL(Proj.Descr,'') as Project,
d.OrdNbr, d.BillofLadingNbr, d.TripAndDeliveryTicketNbr
FROM
OrderDetail d
LEFT JOIN
OrderItemNumbers n ON d.OWID = n.LoadOWID
LEFT JOIN
Bond b ON n.NumberOWID = b.OWID AND n.NumType = 0
LEFT JOIN
PONumbers PO ON n.NumberOWID = PO.OWID AND n.NumType = 1
LEFT JOIN
Job j ON n.NumberOWID = j.OWID AND n.NumType = 2
LEFT JOIN
Project Proj ON n.NumberOWID = Proj.OWID AND n.NumType = 3
WHERE
d.OWID = 'BTBD1004'
Run Code Online (Sandbox Code Playgroud)
这是我得到的结果....
Bond PO Job Project OrdNbr BillofLadingNbr
82001-8177-44 BTBD000063 BTBD000072
4.158 Kingsport BTBD000063 BTBD000072
IME-81-1(118) BTBD000063 BTBD000072
Run Code Online (Sandbox Code Playgroud)
这就是我想要得到的......(基本上扁平化前4列)
Bond PO Job Project OrdNbr BillofLadingNbr
4.158 Kingsport 82001-8177-44, IME-81-1(118) BTBD000063 BTBD000072
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏!谢谢,道格
根据您的示例,似乎没有匹配的记录Bond和Job表.如果有,你会得到这样的东西:
BOND PO JOB PROJECT ORDNBR BILLOFLADINGNBR
Some bond BTBD000063 BTBD000072
4.158 Kingsport BTBD000063 BTBD000072
Some job BTBD000063 BTBD000072
82001-8177-44 BTBD000063 BTBD000072
IME-81-1(118) BTBD000063 BTBD000072
Run Code Online (Sandbox Code Playgroud)
该结果集似乎很"疏",因为你加入OrderItemNumbers直接到你的主查询:此表中有一个明显的一行代表一个子表(PONumbers,Job,Project),所以你会得到一个截然不同的,分开列各加盟.为了避免这种情况,您可以OrderItemNumbers与每个子表连接,然后将此子查询与OrderDetail(通过共享LoadOWID)连接:
SELECT
ISNULL(b.Descr, '') as Bond,
ISNULL(PO.Description, '') as PO,
ISNULL(j.Descr, '') as Job,
ISNULL(Proj.Descr, '') as Project,
d.OrdNbr,
d.BillofLadingNbr,
d.TripAndDeliveryTicketNbr
FROM
OrderDetail d
LEFT JOIN (
SELECT aux.*, n.*
FROM Bond aux INNER JOIN OrderItemNumbers n ON n.NumberOWID = aux.OWID AND n.NumType = 0
) AS b
ON b.LoadOWID = d.OWID
LEFT JOIN (
SELECT aux.*, n.*
FROM PONumbers aux INNER JOIN OrderItemNumbers n ON n.NumberOWID = aux.OWID AND n.NumType = 1
) AS PO
ON PO.LoadOWID = d.OWID
LEFT JOIN (
SELECT aux.*, n.*
FROM Job aux INNER JOIN OrderItemNumbers n ON n.NumberOWID = aux.OWID AND n.NumType = 2
) AS j
ON j.LoadOWID = d.OWID
LEFT JOIN (
SELECT aux.*, n.*
FROM Project aux INNER JOIN OrderItemNumbers n ON n.NumberOWID = aux.OWID AND n.NumType = 3
) AS Proj
ON Proj.LoadOWID = d.OWID
WHERE
d.OWID = 'BTBD1004'
Run Code Online (Sandbox Code Playgroud)
这样你将得到以下结果:
Bond PO Job Project OrdNbr BillofLadingNbr
Some bond 4.158 Kingsport Some job 82001-8177-44 BTBD000063 BTBD000072
Some bond 4.158 Kingsport Some job IME-81-1(118) BTBD000063 BTBD000072
Run Code Online (Sandbox Code Playgroud)
我同意这不完全是你所要求的.你似乎也需要在Project桌子上进行某种"部分旋转" (至少).
从理论上讲,这也是可能的,但我不会这样做.这显然是一个表示要求,在SQL层上实现它的成本太高了.
编辑
为了获得完整的平坦结果集,您可以这样做(基于此SO答案):
DECLARE @bonds VARCHAR(MAX)
DECLARE @numbers VARCHAR(MAX)
DECLARE @jobs VARCHAR(MAX)
DECLARE @projs VARCHAR(MAX)
DECLARE @owid VARCHAR(10) = 'BTBD1004'
SELECT
@bonds = COALESCE(@bonds + ', ', '') + aux.Descr
FROM
Bond aux
INNER JOIN OrderItemNumbers n
ON n.NumberOWID = aux.OWID AND n.NumType = 0
WHERE
n.LoadOWID = @owid
SELECT
@numbers = COALESCE(@numbers + ', ', '') + aux.Description
FROM
PONumbers aux
INNER JOIN OrderItemNumbers n
ON n.NumberOWID = aux.OWID AND n.NumType = 1
WHERE
n.LoadOWID = @owid
SELECT
@jobs = COALESCE(@jobs + ', ', '') + aux.Descr
FROM
Job aux
INNER JOIN OrderItemNumbers n
ON n.NumberOWID = aux.OWID AND n.NumType = 2
WHERE
n.LoadOWID = @owid
SELECT
@projs = COALESCE(@projs + ', ', '') + aux.Descr
FROM
Project aux
INNER JOIN OrderItemNumbers n
ON n.NumberOWID = aux.OWID AND n.NumType = 3
WHERE
n.LoadOWID = @owid
SELECT
@bonds,
@numbers,
@jobs,
@projs,
d.OrdNbr,
d.BillofLadingNbr,
d.TripAndDeliveryTicketNbr
FROM
OrderDetail d
WHERE
d.OWID = @owid
Run Code Online (Sandbox Code Playgroud)
这将导致:
Bond PO Job Project OrdNbr BillofLadingNbr
Some bond 4.158 Kingsport Some job 82001-8177-44, IME-81-1(118) BTBD000063 BTBD000072
Run Code Online (Sandbox Code Playgroud)
如果您获得许多债券x许多PO的x多个工作OWID也是如此.
恕我直言,很好地说明了我试图说的话:是的,它做了你需要的东西,但它是丑陋的地狱.当然,如果你不在乎,继续(只需添加一些触发器,你会觉得它再次是1995年:P).
希望能帮助到你.