仅在临时 table 中保存不同的行

Only saving disinct rows in temporary table

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

但是因为下面的查询发生在一个循环中(我不能把它从循环中取出)假设它循环了 4 家公司,我最终得到一个看起来像这样的列表:

这就是理想中的样子

这是我现在的代码

  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 中?

您可以使用 NOT EXISTS 和相关子查询检查 HAVING 子句中是否存在记录。也就是说,当记录已经存在时,不会选择并插入任何记录。

INSERT INTO #temp_costs_count
            (version_id,
             total_costs,
             cost_included)
            SELECT tc.version_id,
                   count(*),
                   sum(CASE
                         WHEN tc.is_included = 1 THEN
                           1
                         ELSE
                           0
                       END)
                   FROM #temp_costs tc
                   GROUP BY tc.version_id
                   HAVING NOT EXISTS (SELECT *
                                             FROM #temp_costs_count tcc
                                             WHERE tcc.version_id = version_id
                                                   AND tcc.total_costs = count(*)
                                                   AND tcc.cost_included = sum(CASE
                                                                                 WHEN tc.is_included = 1 THEN
                                                                                   1
                                                                                 ELSE
                                                                                   0
                                                                               END));

您可以使用具有不同的子查询:

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

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

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服务器中使用循环的次数(在过去的 12 年里,我几乎每个工作日都在写作 SQL)。根据我的经验,在大约 99.9% 的情况下,有人认为他们需要使用循环,但他们并没有这样做,并且有一个更有效的基于集合的解决方案。

我跳过了您为什么需要这个,只是查看了其他答案 - 但由于其意图似乎是跳过插入已经存在的行,您可以通过将以下内容添加到 #temp table.

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

然后将有效地识别并忽略任何重复项,而无需更改查询