仅在临时表中保存不一致的行

时间:2019-01-25 12:47:10

标签: sql sql-server loops distinct

我有一个查询,我想要在#temp_costs中找到的成本总和,并且我想按version_id将它们分组(以查看公司的总成本) 总成本与某些类型的成本一起计算,其中is_included列为0或1。#temp_costs_count是先前创建的表。

但是,由于以下查询是在一个循环中发生的(我无法从循环中取出它)说它循环了4个公司,因此我得到的清单看起来像这样:

What it looks like right now

这是理想的外观

What it should look like

这是我的代码

  insert into  #temp_costs_count (
    version_id,
    total_costs,
    cost_included
    )

        select  version_id,
                count(*),
                sum(case when is_included = 1 then 1 else 0 end)
        from #temp_costs
        group by version_id

        select * 
        from #temp_costs_count

我确实通过运行

获得了期望的结果
select distinct * 
from #temp_costs_count

但是,有什么方法可以使用更新语句,以便像这样将其保存在#temp_costs_count中吗?

4 个答案:

答案 0 :(得分:3)

您可以使用EXCEPT仅插入表中不存在的记录。例如:

INSERT #temp_costs_count (version_id, total_costs, cost_included)
SELECT  version_id,
        count(*),
        sum(case when is_included = 1 then 1 else 0 end)
FROM    #temp_costs
GROUP BY version_id
EXCEPT
SELECT version_id, total_costs, cost_included
FROM    #temp_costs_count;

或者,如果您以不同的方式定义重复项(例如,只是具有特定version_id的记录),则可以使用NOT EXISTS,例如:

INSERT #temp_costs_count (version_id, total_costs, cost_included)
SELECT version_id,
        count(*),
        sum(case when is_included = 1 then 1 else 0 end)
FROM    #temp_costs AS tc
WHERE NOT EXISTS (SELECT 1 FROM temp_costs_count AS tcc WHERE tcc.version_id = tc.version_id)
GROUP BY version_id;

顺便说一句,我可能一方面可以指望我有必须在SQL Server中使用循环的次数(而且我几乎每个工作日都花了很多时间在最近12年(编写SQL)。根据我的经验,在大约99.9%的情况下,有人认为自己需要使用循环,而实际上并不需要,因此那里有一个效率更高的基于集合的解决方案。

答案 1 :(得分:2)

我跳过了为什么需要这样做,而只是看了其他答案-但由于意图是跳过插入已经存在的行,因此可以通过将以下内容添加到#temp表中来实现。 / p>

CREATE UNIQUE INDEX ix
  ON #temp_costs_count(version_id, total_costs, cost_included)
  WITH (IGNORE_DUP_KEY = ON); 

那么所有重复项都将被有效地识别并忽略,而无需更改查询

答案 2 :(得分:0)

您可以使用0.03699994087219238 0.029999732971191406 (1459667, 1) 和相关子查询来检查HAVING子句中是否没有记录。也就是说,如果记录已经存在,则不会选择任何记录并因此将其插入。

NOT EXISTS

答案 3 :(得分:0)

您可以在以下子查询中使用不同的子查询:

insert into  #temp_costs_count (
version_id,
total_costs,
cost_included
)
select distinct version_id,total_costs,cost_included from (
    select  version_id,
            count(*) as total_costs,
            sum(case when is_included = 1 then 1 else 0 end) as cost_included
    from #temp_costs
    group by version_id

). as q