【问题标题】:Sum all pair of rows in the table对表中的所有行求和
【发布时间】:2019-04-11 21:30:26
【问题描述】:

我需要汇总表中所有可能的原始对的 sql 查询。

我的桌子是这样的:

ID |姓名 |价值 1 |一个 | 100 2 |乙| 150 3 | C | 250 4 | D | 600

在这种情况下,查询输出应该是:

拳名 |第二名 |总和 一个 |乙| 250 一个 | C | 350 一个 | D | 700 乙| C | 400 乙| D | 750 C | D | 850

【问题讨论】:

  • 它是一个表与自身的简单交叉连接,以及一个选择。你的问题是什么,你的sql语句在哪里,你是怎么解决的,你的解决方案哪里错了?
  • 您想要所有组合还是排列?在后一种情况下,{A, B} 与 {B, A} 不同;您正在显示组合...

标签: sql sql-server tsql


【解决方案1】:

试试这个:

select 
    t1.Name as FirstName,
    t2.Name as SecondName,
    t1.Value+t2.Value as Sum
from yourtable as t1
inner join yourtable as t2 on (t1.ID<t2.ID)

【讨论】:

  • 我不知道为什么这被否决了,这是一个正确的答案。
【解决方案2】:

有机会通过cross join 运算符使用很少使用的笛卡尔连接:

select left.Name, right.Name, left.Value + right.Value as Sum
from DataTable left
  cross join DataTable right
order by left.Name, right.Name;

注意,就是输入表很大这样会导致很多行。为避免行以两种方式组合在一起({A,B} 和 {B,A} 出现,{A,A} 出现),可以添加条件。

【讨论】:

  • 这个解决方案的问题是它返回所需行的两倍,因为操作只需要 A-B 行而不是 B-A 行。
  • @GeorgeMenoutis:嗯,他写了条件可以加
  • @dnoeth - 但是可以/应该证明这些条件是什么?
  • 查看我对该问题的评论:尚不清楚需要什么(其他答案假设...)
【解决方案3】:

根据 l.ID &lt; r.ID 的条件进行 INNER JOIN。这确保了行不与自身连接,并且没有1, 22, 1 形式的重复:

DECLARE @t TABLE (ID INT, Name VARCHAR(100), Value INT);
INSERT INTO @t VALUES
(1, 'A', 100),
(2, 'B', 150),
(3, 'C', 250),
(4, 'D', 600);

SELECT l.Name FirstName, r.Name SecondName, l.Value + r.value [Sum]
FROM @t AS l
INNER JOIN @t AS r ON l.ID < r.ID
ORDER BY FirstName, SecondName

【讨论】:

    【解决方案4】:

    这是一种行之有效的方法:

    CREATE TABLE #T (ID INT, Name VARCHAR (10), VALUE INT)
    INSERT INTO #T VALUES (1, 'A', 100), (2, 'B', '150'), (3, 'C', 250), (4, 'D', 600)
    
    SELECT CASE WHEN T.Name < T2.Name THEN (T.Name + T2.Name)  
              ELSE (T2.Name + T.Name) 
          END AS FullName,
          SUM (T.Value) AS TotalValue
    FROM #T AS T
    FULL OUTER JOIN #T AS T2 ON T.Name <> T2.Name
    GROUP BY CASE WHEN T.Name < T2.Name THEN (T.Name + T2.Name)  
                ELSE (T2.Name + T.Name)  END
    

    【讨论】:

    • 与这里的其他答案中的半笛卡尔积相比,似乎过于复杂?
    • 我相信还有更复杂的方法可以获得预期的结果:-)
    • @MatBailie 这是 1 个 case 语句、1 个 join 和 1 个 groupby。明显过于复杂可能会被严重夸大。 :)
    • 与一次连接相比,它要复杂得多(如果name 不是唯一的,可能会返回错误的答案)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多