我的视图(名为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 JOIN
和Rno
值的记录,这样就可以从同一行的每个组合中获取Sno
。我们使用Total
来不排除记录,并且使用LEFT JOIN
标准来防止交换的记录与其对应项一起出现,以及包括任何没有对应项的碰巧有WHERE
Sno
的记录。注意:我是用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
理想情况下,在表中执行此聚合/唯一列表拉取,而不是在子查询上执行自联接(如果您有一个大表)。