В SQL в выражении «group by»: как получить строку, которая чаще всего встречается в группе? - PullRequest
1 голос
/ 01 сентября 2009

Предположим, у нас есть следующая таблица:

Id   A    B
1    10   ABC
2    10   ABC
3    10   FFF
4    20   HHH

В результате выражения "group by A" я хочу получить значение столбца B, которое встречается чаще всего:

select A, mostoften(B) from table group by A;

A    mostoften(B)
10   ABC
20   HHH

Как мне добиться этого в Oracle 10g?

Примечание: в случае связывания (когда чаще всего встречается более одного значения), не имеет значения, какое значение выбрано.

Ответы [ 4 ]

5 голосов
/ 01 сентября 2009
select A, B
from (
  select A, B, ROW_NUMBER() OVER (PARTITION BY A ORDER BY C_B DESC) as rn
  from (
     select A, COUNT (B) as C_B, B
     from table
     group by A, B
  ) count_table
) order_table
where rn = 1;

Вы хотите B с группой МАКС. СЧЕТА по A, B.

1 голос
/ 02 сентября 2009

Решение старой школы, мне потребовалось некоторое время и немного ругательства:)

select a,b
from   ta ta1
group by a,b
having count(*) = (select max(count(*))
                   from   ta ta2
                   where  ta1.a = ta2.a
                   group by b)
0 голосов
/ 01 сентября 2009

Эту проблему можно решить, создав представление для счета в каждой группе A & B:

CREATE VIEW MyTableCounts AS
  SELECT A, B, COUNT(*) C
  FROM MyTable
  GROUP BY A, B;

Теперь мы можем сделать запрос, который находит строку c1, где наибольшее количество. То есть ни одна другая строка с таким же A не имеет большего числа. Поэтому, если мы попытаемся найти строку c2 с большим счетом, совпадение не будет найдено.

SELECT c1.A, c1.B
FROM MyTableCounts c1
LEFT OUTER JOIN MyTableCounts c2
  ON (c1.A = c2.A AND (c1.C < c2.C OR (c1.C = c2.C AND c1.B < c2.B)))
WHERE c2.A IS NULL
ORDER BY c1.A;

Чтобы разрешить привязанные числа (c1.C = c2.C), мы используем значение B, которое, как мы знаем, уникально в данной группе A.

0 голосов
/ 01 сентября 2009

попробуйте это (работает на SQL Server 2005):

declare @yourtable table (rowid int, a int,b char(3))
insert into @yourtable values (1,10,'ABC')
insert into @yourtable values (2,10,'ABC')
insert into @yourtable values (3,10,'FFF')
insert into @yourtable values (4,20,'HHH')

;WITH YourTableCTE AS
(
SELECT
    *, ROW_NUMBER() OVER(partition by A ORDER BY A ASC,CountOfB DESC) AS RowRank
    FROM (SELECT 
              A, B, COUNT(B) AS CountOfB
              FROM @yourtable
              GROUP BY A,B
          ) dt
)
SELECT
    A,B
    FROM YourTableCTE
    WHERE RowRank=1

РЕДАКТИРОВАТЬ без CTE ...

SELECT
    A,B
    FROM (SELECT
              *, ROW_NUMBER() OVER(partition by A ORDER BY A ASC,CountOfB DESC) AS RowRank
              FROM (SELECT 
                        A, B, COUNT(B) AS CountOfB
                        FROM @yourtable
                        GROUP BY A,B
                    ) dt
         ) dt2



    WHERE RowRank=1
...