【问题标题】:Join two table to have each record in first have all rows in second加入两个表以使每个记录在第一个具有所有行在第二个
【发布时间】:2012-06-12 09:32:59
【问题描述】:

我需要加入两个表,其中第一个表中的每一行获取第二个表中的每一行。

例子

表 1: 发票编号、产品编号、数量

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

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

【问题讨论】:

  • 解释您的要求并获得有关 SQL 问题的有用答案的最佳方式是提供一些示例数据,以及您对查询结果的期望。还可以尝试包含您已经尝试过的任何 SQL。
  • What have you tried?。您使用的是什么 DBMS?

标签: sql database join


【解决方案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

编辑

要以您需要使用条件SUMs 之后的格式获取数据,因为我认为 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 的示例

【讨论】:

  • 谢谢,您的查询工作正常。它给出的输出如下 Invoice No Product Code Quantity 001 Product 1 1 001 Product 2 0 有没有办法我可以得到这样的输出 Invoice Num Product1 Product2 Product 3 Discount 001 Quantity Quantity Quantity Total discount 002 Quantity Quantity Quantity Totaldiscount
  • 您需要 PIVOT 输出 - 这是 SQL 2005 或更高版本,还是我们使用的是 MySql?
  • 我使用的是 SQL Server Compact Edition 3.5
  • 能否提供一个示例查询。
【解决方案2】:

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

这是你需要的吗?

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

更新:

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

更新:

需要添加分组并添加到join中以确保lines产品代码被join到products表中

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')

【讨论】:

  • 你能给我一个样品吗?我执行了交叉连接。但它给出的数量是错误的。我怎样才能对结果执行内部连接。
  • 连接给出了正确的记录数,但数量是错误的。它不返回空值
  • 你确定吗?我得到了正确的数字(假设我的理解是正确的)我已经用我得到的结果更新了答案 - 你能用你期望的结果更新问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多