仅在临时 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);
然后将有效地识别并忽略任何重复项,而无需更改查询
我有一个查询,我想要在#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);
然后将有效地识别并忽略任何重复项,而无需更改查询