连接三个表中的数据以填充另一个表

时间:2014-03-24 23:02:36

标签: sql sql-server tsql

我的数据库中有以下表格结构

dbo.Customer:

Customer_Pk CUSTOMER_NAME
1 ACustomer
2 BCustomer
3 CCustomer

dbo.Import

AProduct BProduct CProduct

ACustomer 销售价值1 销售价值2 SaleValue3

BCustomer 销售价值4 销售价值5 SaleValue6

CCustomer 销售价值7 销售价值8 SaleValue9

dbo.Product:

Product_Pk PRODUCT_NAME
1 AProduct
2 BProduct
3 CProduct

我需要加入以填充表dbo.Cost(我有一个单独的成本表的原因是因为相同的产品可能会为不同的客户带来不同的成本)

dbo.cost:

Cost_PK Cost_Value Customer_FK Product_FK
Cell 1 Cell 2 Cell 3 Cell 4
细胞5 细胞6 细胞7 细胞8
细胞9 细胞10 细胞11 细胞12

因此,表dbo.Cost需要描述哪些客户拥有哪些产品以及他们支付了多少。

编辑:SQL创建脚本:

CREATE TABLE [dbo].[Customer](
[Customer_PK] [int] IDENTITY(1,1) NOT NULL,
[Customer_Name] [varchar](100) NOT NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED 
(
[Customer_PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[Product](
    [Product_PK] [int] IDENTITY(1,1) NOT NULL,
    [Product_Name] [varchar](100) NOT NULL,
 CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED 
(
    [Product_PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[Cost](
    [Cost_PK] [int] IDENTITY(1,1) NOT NULL,
    [Cost_Value] [varchar](10) NOT NULL,
    [Customer_FK] [int] NOT NULL,
    [Product_FK] [int] NOT NULL,
 CONSTRAINT [PK_Cost] PRIMARY KEY CLUSTERED 
(
    [Cost_PK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Cost]  WITH CHECK ADD  CONSTRAINT [FK__Cost__Product_FK__5165187F] FOREIGN KEY([Product_FK])
REFERENCES [dbo].[Product] ([Product_PK])
GO

ALTER TABLE [dbo].[Cost] CHECK CONSTRAINT [FK__Cost__Product_FK__5165187F]
GO

ALTER TABLE [dbo].[Cost]  WITH CHECK ADD  CONSTRAINT [FK__Cost__Customer_FK__5070F446] FOREIGN KEY([Customer_FK])
REFERENCES [dbo].[Customer] ([Customer_PK])
GO

ALTER TABLE [dbo].[Cost] CHECK CONSTRAINT [FK__Cost__Customer_FK__5070F446]
GO

1 个答案:

答案 0 :(得分:0)

假设您想要进入Cost表的是与Import表中的Product列和Customer行相交的值,并且Import表中的第一列是名为Customer_Name,我认为您要将Import表格取消。

如果产品数量固定,此查询将执行此操作:

SELECT Cost_Value, Customer.Customer_PK, Product.Product_PK
FROM 
   (SELECT Customer_Name, AProduct, BProduct, CProduct
   FROM Import) p
UNPIVOT
   (Cost_Value FOR Product_Name IN 
      (AProduct, BProduct, CProduct)
)AS unpvt
INNER JOIN Product ON unpvt.Product_Name=Product.Product_Name
INNER JOIN Customer ON unpvt.Customer_Name=Customer.Customer_Name;

但我猜你需要一个动态解决方案(适应Import表中不同数量的产品列),如果是这样(如果上面的假设保持不变),则以下查询应该有效:

DECLARE @cols NVARCHAR(MAX)
SELECT @cols =  STUFF((SELECT ',' + QUOTENAME(Product_Name)
                FROM (
                    SELECT c.name AS Product_Name FROM sys.columns c
                    INNER JOIN sys.tables t ON c.object_id = t.object_id 
                    WHERE t.name = 'Import' AND c.name != 'Customer_Name') x 
                ORDER BY Product_Name FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')

DECLARE @query NVARCHAR(MAX)
SET @query = '  --INSERT Cost (Cost_Value,Customer_FK,Product_FK) 
                SELECT Cost_Value, c.Customer_PK, p.Product_PK
                FROM 
                    (SELECT Customer_Name, ' + @cols + ' FROM Import) p
                UNPIVOT
                    (Cost_Value FOR Product_Name IN (' + @cols + ')
                    ) AS unpvt
                INNER JOIN Product p ON unpvt.Product_Name = p.Product_Name
                INNER JOIN Customer c ON unpvt.Customer_Name = c.Customer_Name;' 

EXEC SP_EXECUTESQL @query

鉴于您的问题中的示例数据,此查询将生成以下输出(可以插入Cost - 我已在注释中注释了插入内容):

Cost_Value           Customer_PK Product_PK
-------------------- ----------- -----------
Sale Value1          1           1
Sale Value2          1           2
Sale Value3          1           3
Sale Value4          2           1
Sale Value5          2           2
Sale Value6          2           3
Sale Value7          3           1
Sale Value8          3           2
Sale Value9          3           3