我希望在SQL Server中按每个组合计算3列值组合。我怎么得到这个?
实施例
Row P1 P2 P3
1 3 10 20
2 4 15 29
3 8 10 16
4 15 4 29
5 10 20 3
Output Should be:
3 10 20 - 2
4 15 29 - 2
8 10 16 - 1

谢谢,
答案 0 :(得分:2)
select vals,count (*) as cnt
from t cross apply (select ' ' + cast (p as varchar(10)) from (values (p1),(p2),(p3)) as t(p) order by p for xml path('')) v (vals)
group by vals
vals cnt
3 10 20 2
4 15 29 2
8 10 16 1
select vals
,count (*) as cnt
from (select cast ((cast ('' as xml)).query('for $i in (sql:column("p1"),sql:column("p2"),sql:column("p3")) order by $i return $i') as varchar(max)) as vals
from t
) t
group by vals
;
vals cnt
------- ---
3 10 20 2
4 15 29 2
8 10 16 1
select [1],[2],[3],count (*) as cnt
from (select row,p,row_number () over (partition by row order by p) as n
from t unpivot (p for col in (p1,p2,p3)) upv
) t pivot (max(p) for n in ([1],[2],[3])) pv
group by [1],[2],[3]
1 2 3 cnt
--- --- --- ---
3 10 20 2
4 15 29 2
8 10 16 1
select [1],[2],[3],count(*) as cnt
from (select (select p from (values (p1),(p2),(p3))as t(p) order by p offset 0 rows fetch first 1 row only) as [1]
,(select p from (values (p1),(p2),(p3))as t(p) order by p offset 1 rows fetch first 1 row only) as [2]
,(select p from (values (p1),(p2),(p3))as t(p) order by p offset 2 rows fetch first 1 row only) as [3]
from t
) t
group by [1],[2],[3]
1 2 3 cnt
--- --- --- ---
3 10 20 2
4 15 29 2
8 10 16 1
答案 1 :(得分:1)
哦,这是一种痛苦。
select p_1, p_2, p_3, count(*) as cnt
from t cross apply
(select max(case when seqnum = 1 then p end) as p_1,
max(case when seqnum = 2 then p end) as p_2,
max(case when seqnum = 3 then p end) as p_3
from (select p, row_number() over (order by p) as seqnum
from (values (p1), (p2), (p3)
) v(p)
) rp
) rp
group by p_1, p_2, p_3;
这是做什么的? cross apply
首先将值展开到单独的行上。然后它枚举值(使用row_number()
,按值排序。这将生成一个序列号,用于按顺序旋转值。
最后,在每行按顺序排列值时,我们可以汇总这些值以获得您要求的计数。
答案 2 :(得分:1)
这是另一种方法,在使用case
表达式时,3个值中的至少一个被赋予c1,第二个最小的c2和最大的c3。此后,它只是一个分组操作。
select c1,c2,c3,count(*)
from (
select case when p1<=p2 and p1<=p3 then p1
when p2<=p1 and p2<=p3 then p2
when p3<=p1 and p3<=p2 then p3 end c1,
case when p1 between p2 and p3 or p1 between p3 and p2 then p1
when p2 between p1 and p3 or p2 between p3 and p1 then p2
when p3 between p1 and p2 or p3 between p2 and p1 then p3 end c2,
case when p2<=p1 and p3<=p1 then p1
when p1<=p2 and p3<=p2 then p2
when p1<=p3 and p2<=p3 then p3 end c3
from t
) x
group by c1,c2,c3
<强> Sample Demo
强>
这里的假设是p1,p2,p3值都不为空。如果它们可以是null
,请在案例表达式中使用coalesce
,具体取决于您希望如何处理这些行以进行计数。