SQL - 将多行连接成一行,包括空值

时间:2014-12-23 06:43:52

标签: sql

我一直在寻找答案,但没有找到。我想这可能是因为我不知道要搜索的条款。另外,这是我的第一篇文章,所以如果我使用不正确的格式,我想道歉。

我需要关注输出:

Invoice | Inv Date | Created by | Destination | Goods $ | Freight | Insurance $ |
33813..| 12 Dec ..| Jack  ........| Cape Town | 250.00 ..| 50.00 ..| 10.00 ...|
33814..| 12 Dec ..| Jenny .........| Durban ......| 5,000.00|  20.00 ..|  ....|


前5列是使用Invoice列作为索引从各个列构建的。

然后我想加上运费和保险。它托管在具有以下布局的不同表格中:

InvCostID | Invoice | Cost Code | Cost Description | Value |<br/>
556 ..........| 33813 .| 1 ...............| Freight ...............| 50.00 |
559 ..........| 33813 .| 2 ...............| Insurance ...........| 10.00 |
570 ..........| 33814 .| 1 ...............| Freight ...............| 20.00 |


问题是我不能只选择要包含的列,因为运费和保险在不同的行中。为了解决这个问题,我创建了两个子表&#39;。一个是成本代码是1(因此,货运表)和一个成本代码2(保险表)。

然后我只需从正确的表中选择值。

问题:如果其中一个成本要素不存在(例如发票33814的保险),我当前的查询会完全从结果中排除该发票。 (使用上面的表格,我的下面的代码只会显示发票33813。

select 
IT.Invoice as 'Invoice',
IT.InvDate as 'Inv Date',
UT.UserFullName as 'Created by',
IT.DestinationDescription as 'Destination',
IT.USDVal as 'Goods $',
FREIGHTLIST.Value as 'FREIGHT $',
INSURANCELIST.Value as 'INSURANCE $'

from InvoiceTable IT,
UserTable UT,
(select * from SundryCostTable where CostCode = 1) as FREIGHTLIST,
(select * from SundryCostTable  where CostCode = 2) as INSURANCELIST

where IT.InvDate > '2014-12-01'
and IT.UserId = UT.UserId
and IT.Invoice = FREIGHTLIST.Invoice
and IT.Invoice = INSURANCELIST.Invoice

请帮忙。

谢谢 尼科

(我正在使用SQL Server Management Studio来运行查询)

2 个答案:

答案 0 :(得分:0)

select 
IT.Invoice as 'Invoice',
IT.InvDate as 'Inv Date',
UT.UserFullName as 'Created by',
IT.DestinationDescription as 'Destination',
IT.USDVal as 'Goods $',
FREIGHTLIST.Value as 'FREIGHT $',
INSURANCELIST.Value as 'INSURANCE $'

from InvoiceTable IT
join UserTable UT on IT.UserId = UT.UserId
left join SundryCostTable as FREIGHTLIST on CostCode = 1 and IT.Invoice = FREIGHTLIST.Invoice
left join SundryCostTable as INSURANCELIST on CostCode = 2 and IT.Invoice = INSURANCELIST.Invoice

where IT.InvDate > '2014-12-01'

请注意使用LEFT JOIN,以便在与FREIGHTLIST或INSURANCELIST不匹配时不排除IT和UT的行。

查看this帖子,详细了解JOIN的使用情况。

答案 1 :(得分:0)

您也可以使用子查询而不是Aquillo所描述的LEFT JOIN。以下查询负责FREIGHT和INSURANCE的NULL值。

SELECT 
IT.Invoice as 'Invoice',
IT.InvDate as 'Inv Date',
UT.UserFullName as 'Created by',
IT.DestinationDescription as 'Destination',
IT.USDVal as 'Goods $',
ISNULL((select Top 1 Value from SundryCostTable where CostCode = 1 And SundryCostTable.Invoice=IT.Invoice),0) as 'FREIGHT $',
ISNULL((select Top 1 Value from SundryCostTable where CostCode = 2 And SundryCostTable.Invoice=IT.Invoice),0) as 'INSURANCE $'

from InvoiceTable IT,
UserTable UT

where IT.InvDate > '2014-12-01'
and IT.UserId = UT.UserId