【问题标题】:sum from two tables insert if not exists如果不存在,则插入两个表的总和
【发布时间】:2012-12-11 08:57:06
【问题描述】:

我有一种情况,我想对两个表之间的差异求和。问题是第二个表中可以存在一行,然后我想将其插入为新行。

SELECT T1.seller, T1.code, T1.amount - T2.amount

看图说明

LINK

【问题讨论】:

  • 您使用的是什么 DBMS?你试过什么?
  • SELECT T1.seller, T1.code, (T1.amount - T2.amount) as TAmountSum from T1 inner join T2 on T1.ID = T2.ID
  • 我使用 SQL2008 SELECT T1.seller, T1.shortcutcode, (T1.amount - T2.amount) as totalamount FROM Table1 T1 inner join Table2 T2 on T1.seller = T2.seller 但这会重复行
  • SELECT distinct T1.seller, T1.shortcutcode, (T1.amount - T2.amount) as totalamount FROM Table1 T1 inner join Table2 T2 on T1.seller = T2.seller
  • 什么是表格列?

标签: sql sql-server-2008 sum full-outer-join


【解决方案1】:
 DECLARE @T1 TABLE(
    seller VARCHAR(10),
    code VARCHAR(3) NULL,
    amount MONEY
)

 DECLARE @T2 TABLE(
    seller VARCHAR(10),
    code VARCHAR(3) NULL,
    amount MONEY
)

INSERT INTO @T1 VALUES
('VL',NULL,1),
('VL','317',70005.6)

INSERT INTO @T2 VALUES
('VL',NULL,0.5),
('VL','500',4450)

SELECT seller,code,SUM(amount) [amount] FROM 
(
SELECT * FROM @T1
UNION ALL
SELECT seller,code,-amount as amount FROM @T2
) T
GROUP BY seller,code

【讨论】:

    【解决方案2】:

    您需要进行完整的外部连接 - 然后总结一下。如果您只运行内部查询,您将获得每个可能的行组合(在 t1 中不包含,在 t1 和 t2 中都存在,在 t2 中不包含) - 然后将其分组并求和。

    SELECT  Seller ,
            Code ,
            SUM(Tab1_amt - Tab2_amt) AS Amount
    FROM    ( SELECT    COALESCE(tab1.Seller, tab2.Seller) AS Seller ,
                        COALESCE(tab1.code, tab2.code) AS Code ,
                        COALESCE(tab1.amount, 0) AS tab1_amt ,
                        COALESCE(tab2.amount, 0) AS tab2_amt
              FROM      tab1
                        FULL OUTER JOIN tab2 ON tab1.seller = tab2.seller
                                                AND tab1.code = tab2.code
            ) AS Tbl
    GROUP BY Seller ,
            Code
    

    SQLFiddle Demo

    【讨论】:

      【解决方案3】:

      这样的?你没有告诉要插入什么表到“因此 tableX”

      insert into tableX (seller,code,amount) values (T1.seller, T1.code, T1.amount -T2.amount)
      select count(*) from table2 having count(*) < 1
      

      请注意,您将过滤器作为选择语句放在插入应用过滤器之后 你没有指定你需要什么类型的 sql,所以我不能说这是否有效

      【讨论】:

        【解决方案4】:

        我认为您需要一个 FULL JOIN(除非您确实希望将行插入到第一个表中)

        SELECT  COALESCE(t1.Seller, t2.Seller) AS Seller,
                COALESCE(t1.Code, t2.Code) AS Code,
                COALESCE(t1.Amount, 0) - COALESCE(t2.Amount, 0) AS Amount
        FROM    Table1 t1
                FULL JOIN Table2 t2
                    ON t1.Seller = t2.Seller
                    AND COALESCE(t1.Code, 0) = COALESCE(t2.Code, 0);
        

        如果您确实需要向表 1 插入行,则需要执行 2 次操作,首先插入,然后选择:

        INSERT Table1 (Seller, Code, Amount)
        SELECT  t2.Seller, t2.Code, 0 AS Amount
        FROM    Table2 t2
        WHERE   NOT EXISTS
                (   SELECT  1
                    FROM    Table1 t1
                    WHERE   t1.Seller = t2.Seller
                    AND     COALESCE(t1.Code, 0) = COALESCE(t2.Code, 0)
                );
        
        SELECT  t1.Seller, 
                t1.Code, 
                t1.Amount - COALESCE(t2.Amount, 0) AS Amount
        FROM    Table1 t1
                LEFT JOIN Table2 t2
                    ON t1.Seller = t2.Seller
                    AND COALESCE(t1.Code, 0) = COALESCE(t2.Code, 0);
        

        编辑

        如果每个表中的行不是唯一的并且您需要对它们求和,那么您需要在子查询中进行求和,因为 JOIN 将引入交叉连接:

        考虑这些数据

        Table1
        Seller  Code    Amount
        VL      500     10
        VL      500     20
        
        Table2
        Seller  Code    Amount
        VL      500     30
        VL      500     5
        

        当你加入这个你会得到:

        t1.Seller   t1.Code t1.Amount   t2.Seller   t2.Code t2.Amount
        VL          500     10          VL          500     30
        VL          500     10          VL          500     5
        VL          500     20          VL          500     30
        VL          500     20          VL          500     5
        

        差的总和是 -10 而不是 -5。

        SELECT  COALESCE(t1.Seller, t2.Seller) AS Seller,
                COALESCE(t1.Code, t2.Code) AS Code,
                COALESCE(t1.Amount, 0) - COALESCE(t2.Amount, 0) AS Amount
        FROM    (   SELECT  Seller, Code, SUM(Amount) AS Amount
                    FROM    Table1 
                    GROUP BY Seller, Code
                ) t1
                FULL JOIN 
                (   SELECT  Seller, Code, SUM(Amount) AS Amount
                    FROM    Table2 
                    GROUP BY Seller, Code
                ) t2
                    ON t1.Seller = t2.Seller
                    AND COALESCE(t1.Code, 0) = COALESCE(t2.Code, 0);
        

        编辑 2

        Daniel's answer 中的 UNION 方法将比 FULL JOIN 执行得更好:

        SELECT  Seller, Code, Amount = SUM(Amount)
        FROM    (   SELECT  Seller, Code, Amount
                    FROM    Table1
                    UNION
                    SELECT  Seller, Code, -Amount
                    FROM    Table2
                ) t
        GROUP BY Seller, Code
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-09
          • 2018-09-17
          • 2013-02-23
          • 2014-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-11
          相关资源
          最近更新 更多