SQL GROUP BY with columns which contain mirrored values

帅比萌擦擦* 提交于 2019-12-11 07:32:33

问题


Sorry for the bad title. I couldn't think of a better way to describe my issue.

I have the following table:

Category | A | B
A        | 1 | 2
A        | 2 | 1
B        | 3 | 4
B        | 4 | 3

I would like to group the data by Category, return only 1 line per category, but provide both values of columns A and B.

So the result should look like this:

category | resultA | resultB
A        | 1       | 2
B        | 4       | 3

How can this be achieved?

I tried this statement:

SELECT category, a, b
FROM table
GROUP BY category

but obviously, I get the following errors:

Column 'a' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Column 'b' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

How can I achieve the desired result?


回答1:


Try this:

SELECT category, MIN(a) AS resultA, MAX(a) AS resultB
FROM table
GROUP BY category

If the values are mirrored then you can get both values using MIN, MAX applied on a single column like a.




回答2:


Seams you don't really want to aggregate per category, but rather remove duplicate rows from your result (or rather rows that you consider duplicates).

You consider a pair (x,y) equal to the pair (y,x). To find duplicates, you can put the lower value in the first place and the greater in the second and then apply DISTINCT on the rows:

select distinct
  category,
  case when a < b then a else b end as attr1,
  case when a < b then b else a end as attr2
from mytable;



回答3:


Considering you want a random record from duplicates for each category.

Here is one trick using table valued constructor and Row_Number window function

;with cte as
(
SELECT *,
       (SELECT Min(min_val) FROM (VALUES (a),(b))tc(min_val)) min_val,
       (SELECT Max(max_val) FROM (VALUES (a),(b))tc(max_val)) max_val
FROM   (VALUES ('A',1,2),
               ('A',2,1),
               ('B',3,4),
               ('B',4,3)) tc(Category, A, B) 
)
select Category,A,B from 
(
Select Row_Number()Over(Partition by category,max_val,max_val order by (select NULL)) as Rn,*
From cte
) A
Where Rn = 1


来源:https://stackoverflow.com/questions/42026970/sql-group-by-with-columns-which-contain-mirrored-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!