好的,我有一个输入订单的系统,每个订单都可以附加任意数量的债券,工作和项目编号。 OrderDetails
表包含orderID
用于转到OrderNumbers
表并获取此订单的所有附加“数字”,然后根据此处找到的numType
列,它转到三个表中的一个(债券,工作,项目)并检索为用户显示和打印的实际数字。
这意味着,如果该订单附加了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'
以下是我得到的结果......
Bond PO Job Project OrdNbr BillofLadingNbr
82001-8177-44 BTBD000063 BTBD000072
4.158 Kingsport BTBD000063 BTBD000072
IME-81-1(118) BTBD000063 BTBD000072
这就是我想要的......(基本上是扁平化前4列)
Bond PO Job Project OrdNbr BillofLadingNbr
4.158 Kingsport 82001-8177-44, IME-81-1(118) BTBD000063 BTBD000072
任何帮助表示赞赏! 谢谢, 道格
答案 0 :(得分:6)
根据您的示例,似乎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
该结果集似乎“稀疏”,因为您将OrderItemNumbers
直接加入到主查询中:此表为每个子表都有一个不同的行(PONumbers
,Job
,{ {1}}),因此您将每个联接放在一个不同的分隔行中。为了避免这种情况,您可以将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'
我同意这不完全是你所要求的。您似乎还需要在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
表(至少)上进行某种“部分转动”。
修改强>
为了获得完整的平面结果集,您可以这样做(基于this SO answer):
Project
这将导致:
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
如果您为同一Bond PO Job Project OrdNbr BillofLadingNbr
Some bond 4.158 Kingsport Some job 82001-8177-44, IME-81-1(118) BTBD000063 BTBD000072
获得许多债券x许多PO的x多个工作,它就有效。
IMHO很好地说明了我试图说的话:是的,它可以满足您的需要,但它实际上是丑陋的。当然,如果你不在乎,继续(只需添加一些触发器,你会觉得它再次是1995年:P)。
希望它有所帮助。