将子查询返回的结果行与外部查询结果插入表中

时间:2018-09-07 07:01:22

标签: sql sql-server

这是表定义,这将是结果的目标表

CREATE TABLE [dbo].[CONTRIBUTION_MARGIN_ACCOUNTING] (
    [ID_CONTRIBUTION_MARGIN_ACCOUNTING] [INT] IDENTITY(1000001, 1) NOT NULL
   ,[ID_CUSTOMER_ACCOUNT_POSITION]      [INT]            NOT NULL
   ,[TYP]                               [CHAR](1)        NULL
   ,[CREDIT_TYP]                        [CHAR](1)        NULL
   ,[BILL_DATE]                         [DATETIME]       NULL
   ,[BILL_NO]                           [NVARCHAR](20)   NULL
   ,[POSITION]                          [SMALLINT]       NULL
   ,[CUSTOMER_NO]                       [NVARCHAR](255)  NULL
   ,[CHARGE]                            [NVARCHAR](20)   NULL
   ,[Amount]                            [DECIMAL](18, 6) NULL
   ,CONSTRAINT [PK_CONTRIBUTION_MARGIN_ACCOUNTING] PRIMARY KEY CLUSTERED (
        [ID_CONTRIBUTION_MARGIN_ACCOUNTING] 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

ALTER TABLE [dbo].[CONTRIBUTION_MARGIN_ACCOUNTING] WITH CHECK
    ADD CONSTRAINT [CustomerAccountPosition_CONTRIBUTION_MARGIN_ACCOUNTING]
    FOREIGN KEY([ID_CUSTOMER_ACCOUNT_POSITION])
    REFERENCES [dbo].[CUSTOMER_ACCOUNT_POSITION]([ID_CUSTOMER_ACCOUNT_POSITION])
    ON DELETE CASCADE
GO

要求是:由于要在子查询中找到许多唯一的组合CONTRIBUTION_MARGIN_ACCOUNTING ID_CUSTOMERACCOUNT_POSITION,因此将有许多新记录插入表Amount

以下查询给出了错误,因为通常Subquery返回多行

SELECT krp.ID_CUSTOMER_ACCOUNT_POSITION
      ,kr.RECEIPT_TYP AS TYP
      ,krp.CALCULATION_TYP AS CREDIT_TYP
      ,kr.BILL_DATE AS BILL_DATE
      ,kr.NO AS BILL_NO
      ,krp.POSITION AS POSITION
      ,kun.NO AS CUSTOMER_NO
      ,(CASE WHEN krp.ID_DELIVERY_POSITION IS NOT NULL
        THEN (SELECT mge.CHARGE_NO AS chr
                    ,SUM(loadingPackage.AMOUNT) AS Amount
              FROM dbo.LOADING_PACKAGE AS loadingPackage
              INNER JOIN dbo.MATERIAL_COMPONENT AS mbe ON loadingPackage.ID_MATERIAL_COMPONENT = mbe.ID_MATERIAL_COMPONENT
              INNER JOIN dbo.MATERIAL_PACK AS mge ON mbe.ID_MATERIAL_COMPONENT = mge.ID_MATERIAL_COMPONENT
              WHERE loadingPackage.ID_DELIVERY_POSITION = DELIVERYPosition.ID_DELIVERY_POSITION
              GROUP BY mge.CHARGE_NO
                      ,loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION
              )
             WHEN krp.ID_DELIVERY_POSITION IS NULL
             THEN (SELECT mge.CHARGE_NO AS ch
                         ,SUM(loadingPackage.AMOUNT) AS Amount
                   FROM dbo.LOADING_PACKAGE AS loadingPackage
                   INNER JOIN dbo.MATERIAL_COMPONENT AS mbe ON loadingPackage.ID_MATERIAL_COMPONENT = mbe.ID_MATERIAL_COMPONENT
                   INNER JOIN dbo.MATERIAL_PACK AS mge ON mbe.ID_MATERIAL_COMPONENT = mge.ID_MATERIAL_COMPONENT
                   WHERE loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION = krp.ID_CUSTOMER_ACCOUNT_POSITION
                   GROUP BY mge.CHARGE_NO
                           ,loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION
             )
            ELSE
                NULL
            END) AS CHARGE
FROM dbo.CUSTOMER ACCOUNT_POSITION AS krp
INNER JOIN dbo.CUSTOMER ACCOUNT AS kr ON kr.ID_CUSTOMER_ACCOUNT = krp.ID_CUSTOMER ACCOUNT
LEFT OUTER JOIN dbo.AMOUNT AS deck ON krp.ID_CUSTOMER_ACCOUNT_POSITION = deck.ID_CUSTOMER_ACCOUNT_POSITION
LEFT OUTER JOIN dbo.DELIVERY_POSITION AS DELIVERYPosition ON krp.ID_DELIVERY_POSITION = DELIVERYPosition.ID_DELIVERY_POSITION
LEFT OUTER JOIN dbo.CUSTOMER AS kun ON kun.ID_CUSTOMER = kr.ID_CUSTOMER
WHERE deck.ID_CUSTOMER_ACCOUNT_POSITION IS NULL
AND kr.STATUS = 'A' ;

不确定如何实现此示例,例如:如果某些ID_CUSTOMER ACCOUNT_POSITION有2个Amounts,我们应该在表CONTRIBUTION_MARGIN_ACCOUNTING中创建2个具有相同ID_CUSTOMER的记录ACCOUNT_POSITION,但金额不同。

样本数据

enter image description here

1 个答案:

答案 0 :(得分:0)

因此将那些子查询放在from部分,加入他们:

SELECT ...
      ,ISNULL(charge_dlvr.CHARGE_NO, charge_pkg.CHARGE_NO) AS CHARGE_NO
      ,ISNULL(charge_dlvr.Amount, charge_pkg.Amount) AS Amount
FROM dbo.CUSTOMER ACCOUNT_POSITION AS krp
...
OUTER APPLY
(SELECT mge.CHARGE_NO
                    ,SUM(loadingPackage.AMOUNT) AS Amount
              FROM dbo.LOADING_PACKAGE AS loadingPackage
              INNER JOIN dbo.MATERIAL_COMPONENT AS mbe ON loadingPackage.ID_MATERIAL_COMPONENT = mbe.ID_MATERIAL_COMPONENT
              INNER JOIN dbo.MATERIAL_PACK AS mge ON mbe.ID_MATERIAL_COMPONENT = mge.ID_MATERIAL_COMPONENT
              WHERE loadingPackage.ID_DELIVERY_POSITION = DELIVERYPosition.ID_DELIVERY_POSITION
              GROUP BY mge.CHARGE_NO
                      ,loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION
) charge_dlvr
OUTER APPLY
(SELECT mge.CHARGE_NO
                         ,SUM(loadingPackage.AMOUNT) AS Amount
                   FROM dbo.LOADING_PACKAGE AS loadingPackage
                   INNER JOIN dbo.MATERIAL_COMPONENT AS mbe ON loadingPackage.ID_MATERIAL_COMPONENT = mbe.ID_MATERIAL_COMPONENT
                   INNER JOIN dbo.MATERIAL_PACK AS mge ON mbe.ID_MATERIAL_COMPONENT = mge.ID_MATERIAL_COMPONENT
                   WHERE loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION = krp.ID_CUSTOMER_ACCOUNT_POSITION
                     AND krp.ID_DELIVERY_POSITION IS NULL
                   GROUP BY mge.CHARGE_NO
                           ,loadingPackage.ID_CUSTOMER_ACCOUNT_POSITION
) charge_pkg
WHERE deck.ID_CUSTOMER_ACCOUNT_POSITION IS NULL