我的视图(名为view1)如下所示:

Sno |  Rno   |  Total
1   |  2     |   5
2   |  1     |   6
3   |  4     |   5
4   |  5     |   8

sno:发件人号码,rno:收件人号码,total:从sno发送到rno的邮件数
我应该编写一个查询,以便查询结果:
案例1:如果我们在表中有两个方向的记录,如上表中的1到2和2到1,我们应该将两个计数相加,并将它们显示在一行中,即此处
我们将在输出中得到1121(1-2是5,2-1是6)
因为输出中已经有1 2 11,所以查询不应该在输出/结果集中包含2 1 11。
案例2:如果我们有一个方向的记录,也就是说,这里有3到4的记录,但是没有4到3的记录
在这种情况下,我们只需要在输出中返回345。
最后,我们需要合并/合并这两个案例的结果并将其作为结果返回。
我尝试了各种方法,但没有一种能达到预期的效果。我的查询如下:
select a.sno,a.rno,a.total from view1 a where not exists(select * from view1 b where a.sno=b.rno and a.rno=b.sno)
union
select a1.sno,a1.rno, (a1.total+b1.total) as total from view1 a1, view1 b1 where a1.sno=b1.rno and a1.rno=b1.sno;

请你看一下,看能不能帮我找出正确的解决办法?

最佳答案

你可以用一个self来实现这一点:

SELECT a.Sno
      ,a.Rno
      ,a.Total + COALESCE(b.Total,0) AS Total
FROM Table1 a
LEFT JOIN Table1 b
 ON a.Sno = b.Rno
 AND a.Rno = b.Sno
WHERE a.Sno < a.Rno
   OR b.Rno IS NULL

演示:SQL Fiddle
说明:这里的想法是加入已交换LEFT JOINRno值的记录,这样就可以从同一行的每个组合中获取Sno。我们使用Total来不排除记录,并且使用LEFT JOIN标准来防止交换的记录与其对应项一起出现,以及包括任何没有对应项的碰巧有WHERESno的记录。
注意:我是用sql server做的,但是它应该可以跨dbms工作。
更新:根据您的注释,您的表中似乎没有不同的Rno/Sno值对,您可以通过Rno或在使用上述查询之前聚合来解决此问题,具体取决于所需的输出:
SELECT a.Sno
      ,a.Rno
      ,a.Total + COALESCE(b.Total,0) AS Total
FROM (SELECT Sno,Rno,SUM(Total) AS Total   --Or `SELECT DISTINCT Sno,Rno,Total` and remove `GROUP BY`
              FROM Table1
              GROUP BY Sno,Rno) a
LEFT JOIN (SELECT Sno,Rno,SUM(Total) AS Total   --Or `SELECT DISTINCT Sno,Rno,Total` and remove `GROUP BY`
              FROM Table1
              GROUP BY Sno,Rno) b
 ON a.Sno = b.Rno
 AND a.Rno = b.Sno
WHERE a.Sno < a.Rno
   OR b.Rno IS NULL

理想情况下,在表中执行此聚合/唯一列表拉取,而不是在子查询上执行自联接(如果您有一个大表)。

10-06 07:35