加入两个表以使每个记录在第一个中具有所有行

时间:2012-06-12 09:32:59

标签: sql database join

我需要连接两个表,其中第一个表中的每一行都获得第二个表中的每一行。

实施例

表1: InvoiceNo,产品代码,数量

表2: 产品代码,产品名称

在表1中,对于每张发票记录,我只有一些产品,但在输出中,我必须获取每张发票的所有产品,如果该产品未包含在发票中,则将数量保持为0。 我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

您是否尝试过CROSS JOIN - 这会为每个Invoice(table2)生成Product(table1)中的所有行。然后你可以INNER JOIN到发票行表来获得总数。

这是你需要的吗?

http://sqlfiddle.com/#!3/e2f66/4

更新:

(oops)当我说INNER join我的意思是LEFT,否则你消除了null:)

更新:

需要添加分组并添加到联接以确保行产品代码已连接到产品表

http://sqlfiddle.com/#!3/e2f66/14

我得到了这些结果:

INVOICENO    PRODUCTCODE    QUANTITY   
INV0001      PROD01         1
INV0001      PROD02         2
INV0001      PROD03         0
INV0002      PROD01         0
INV0002      PROD02         0
INV0002      PROD03         0
INV0003      PROD01         0
INV0003      PROD02         0
INV0003      PROD03         0

当然这是基于以下数据:

CREATE TABLE InvoiceHeader
(
  InvoiceNo varchar(10)
)

CREATE TABLE InvoiceLines
(
  InvoiceNo varchar(10),
  ProductCode varchar(10),
  Quantity int
)

CREATE TABLE Products
(
  ProductCode varchar(10)
)

INSERT INTO InvoiceHeader VALUES ('INV0002')
INSERT INTO InvoiceHeader VALUES ('INV0001')
INSERT INTO InvoiceHeader VALUES ('INV0003')

INSERT INTO InvoiceLines VALUES ('INV0001', 'PROD01', 1)
INSERT INTO InvoiceLines VALUES ('INV0001', 'PROD02', 2)

INSERT INTO Products VALUES ('PROD01')
INSERT INTO Products VALUES ('PROD02')
INSERT INTO Products VALUES ('PROD03')

答案 1 :(得分:1)

我不得不猜测你的牌桌名称,但我认为这可以按要求运作:

SELECT  InvoiceNo, 
        ProductName, 
        SUM(CASE WHEN Invoice.ProductCode = Product.ProductCode THEN Quantity ELSE 0 END) AS Quantity
FROM    Invoice, Product
GROUP BY InvoiceNo, ProductName

修改

在您需要使用条件SUM之后,以您所使用的格式获取数据,因为我认为SQL-Server CE不支持PIVOT。这样的事情对你有用:

SELECT  InvoiceNum,
        SUM(CASE WHEN ProductCode = 'P1' THEN Quantity ELSE 0 END) [Product 1],
        SUM(CASE WHEN ProductCode = 'P2' THEN Quantity ELSE 0 END) [Product 2],
        SUM(CASE WHEN ProductCode = 'P3' THEN Quantity ELSE 0 END) [Product 3]
FROM    Invoice
GROUP BY InvoiceNum

这只有在您编写代码时知道所有产品的情况下才有效。如果这可能会更改,您可以使用动态SQL创建上述查询,但动态添加产品,以便在添加新产品时不需要更改查询。我没有在CE上对此进行过测试,但我认为没有任何理由不起作用。

DECLARE @SQL NVARCHAR(MAX)

SELECT  @SQL = COALESCE(@SQL, '') + ', SUM(CASE WHEN ProductCode = ''' + ProductCode + ''' THEN Quantity ELSE 0 END) ' + QUOTENAME(ProductName)
FROM    Product

SET @SQL = N'SELECT InvoiceNum' + @SQL + N'FROM Invoice GROUP BY InvoiceNum'

EXECUTE SP_EXECUTESQL  @SQL

我在SQL Fiddle

上使用了SQL-Server 2008R2