sql - 根据另一列的不同值聚合一列

标签 sql sql-server sql-server-2008

这个场景基于 another question 中的模式,我对任何关于模式有效性的讨论都不感兴趣!

我很想知道 SQL Server 中是否有任何好的技术可以根据另一列( amount1 )的不同值来执行一列(下面的 id1 )的聚合。

下面的 Plan1 扫描 table1 两次,通过 p_id 执行两次聚合,然后将结果连接在一起。这似乎可以改进。在某些情况下,查询 2 可能会返回错误的结果,而且计划更糟!

有任何想法吗?

数据线

IF OBJECT_ID('tempdb..#table1') IS NOT NULL DROP TABLE #table1;
IF OBJECT_ID('tempdb..#table2') IS NOT NULL DROP TABLE #table2;

CREATE TABLE #table1 (id1 int primary key nonclustered, amount1 int, p_id int);
CREATE CLUSTERED INDEX ix ON #table1 (p_id,id1);
INSERT INTO #table1
SELECT 1,500,10 UNION ALL
SELECT 2,700,20 UNION ALL
SELECT 3,500,10 UNION ALL
SELECT 4,450,20 UNION ALL
SELECT 5,300,10;

CREATE TABLE #table2 (id2 int primary key, amount2 int, id1 int);
INSERT INTO #table2
SELECT 1,300,1 UNION ALL
SELECT 2,200,1 UNION ALL
SELECT 3,200,2 UNION ALL
SELECT 4,500,2 UNION ALL
SELECT 5,400,3 UNION ALL
SELECT 6,150,4 UNION ALL
SELECT 7,300,4 UNION ALL
SELECT 8,300,5;

查询 1
WITH t1
     AS (SELECT p_id,SUM(amount1) AS total1
         FROM   #table1
         GROUP  BY p_id),
     t2
     AS (SELECT p_id,SUM(amount2) AS total2
         FROM   #table2 table2
                JOIN #table1 table1
                  ON table1.id1 = table2.id1
         GROUP  BY p_id)
SELECT t1.p_id,total1,total2
FROM   t1
       JOIN t2
         ON t1.p_id = t2.p_id  

方案一

Execution Plan 1

查询 2
SELECT table1.p_id, 
       FLOOR(SUM(DISTINCT amount1 + table1.id1/100000000.0)) AS total1, 
       SUM(amount2) AS total2
FROM #table1 table1 JOIN #table2 table2 ON table1.id1=table2.id1
GROUP BY table1.p_id

方案二

Execution Plan 1

最佳答案

好吧,@Quassnoi 解决方案看起来不错。无论如何,对于 SQL Server 2005+,您可以使用 PARTITION BY子句尝试进行更简单的查询,但执行计划并不是更好,尽管这并不一定意味着效率更高或更低。

SELECT A.p_id, MIN(amount1) total1, SUM(amount2) total2
FROM (SELECT p_id, id1, SUM(amount1) OVER(PARTITION BY p_id) amount1 FROM #table1) A
JOIN #table2 B
ON A.id1 = B.id1
GROUP BY A.p_id

关于sql - 根据另一列的不同值聚合一列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4564348/

相关文章:

sql - 检查给定日期是否在日期范围内

sql-server-2008 - SSRS 中的运行值图表 - 如何让每个系列从 0 开始?

mysql - 如何在mysql中找到第二高的薪水

SQL从相关键中获取记录组合列表

android - 在数据库更改 Android 时得到通知

sql - 在 OLEDB 源变量窗口中读取 for-each-loop 容器变量

sql - Management Studio 中的结果集列宽

sql-server-2008 - 我应该在事实表中的这些外键上放置一个非聚集索引吗

sql - MS SQL 相当于 ON DUPLICATE KEY UPDATE/UPSERT

mysql - 嵌套 SQL 语句未按预期计算 SUM