Напишите SQL запрос, который находит наиболее распространенное имя (S), ошибки - PullRequest
0 голосов
/ 12 февраля 2020

Мне нужно написать запрос, который находит наиболее распространенные имена, учитывая таблицу с именем USERS_FAKE U.

Моя проблема заключается в том, что мне удалось написать запрос, который возвращает ТОЛЬКО 1 общее имя. Но если имя «Боб» появляется 6 раз, что делает его наиболее распространенным именем, а также есть другие имена, которые появляются 6 раз (например, «Майк»), мой запрос будет возвращать только «Боб». Мой запрос должен вернуть Боба и Майка, поскольку они имеют одинаковое количество вхождений.

Попытка в MCRE:

-- The table we are working with
CREATE TABLE USERS_FAKE (
    USER_ID NUMBER PRIMARY KEY,
    FIRST_NAME VARCHAR2(100) NOT NULL,
    LAST_NAME VARCHAR2(100) NOT NULL
);

-- Test Data, to test that we return the Most Common First Name(s)
-- (clearly there are 2 Most Common First Name(s): Bob and Mike)
INSERT INTO USERS_FAKE VALUES(5,  'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(6,  'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(7,  'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(8,  'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(9,  'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(10, 'Bob',  'Io');
INSERT INTO USERS_FAKE VALUES(11, 'Mike',  'Ganymede');
INSERT INTO USERS_FAKE VALUES(12, 'Mike',  'Ganymede');
INSERT INTO USERS_FAKE VALUES(13, 'Mike',  'Ganymede');
INSERT INTO USERS_FAKE VALUES(14, 'Mike',  'Ganymede');
INSERT INTO USERS_FAKE VALUES(15, 'Mike',  'Ganymede');
INSERT INTO USERS_FAKE VALUES(16, 'Mike',  'Ganymede');

Мне нужно написать простой запрос, использующий агрегацию + WHERE предложение, но вы объедините два в SQL. Это в Oracle, и я должен использовать ROWNUM, LIMIT не работает в моей среде.

Ответы [ 3 ]

1 голос
/ 12 февраля 2020

Агрегирование не разрешено в предложении WHERE. Вы хотели, чтобы запрос возвращал имя, связанное с количеством вхождений наиболее часто встречающихся имен. Вместо этого следует использовать предложение HAVING, поскольку предложение HAVING используется для фильтрации групп после агрегирования в SQL.

См. Пример ниже:

SELECT DISTINCT FIRST_NAME, COUNT(FIRST_NAME) AS MOST_FREQUENT 
FROM USERS_FAKE
GROUP BY FIRST_NAME
HAVING COUNT(FIRST_NAME) = (SELECT COUNT(FIRST_NAME) AS NUM_FREQUENCY 
                            FROM USERS_FAKE
                            GROUP BY FIRST_NAME
                            ORDER BY NUM_FREQUENCY DESC
                            LIMIT 1)
;

Также я лично рекомендуем row_number():

SELECT T.FIRST_NAME
FROM (
       SELECT N.FIRST_NAME AS FIRST_NAME
            , ROW_NUMBER() OVER (ORDER BY N.NUM_FREQUENCY DESC) AS ROW_NUM
       FROM (
               SELECT FIRST_NAME
                    , COUNT(FIRST_NAME) AS NUM_FREQUENCY 
               FROM USERS_FAKE
               GROUP BY FIRST_NAME
               ORDER BY NUM_FREQUENCY
            ) AS N
      ) AS T
WHERE T.ROW_NUM = 1
;

ROW_NUMBER() ранжирует имена по их вхождению, затем запрос возвращает первую строку, которая относится к наиболее частому имени. В этом случае ROW_NUMBER() не лучшее решение. Однако это может быть простой способ реализовать сценарий «происшествия имеет значение» ios.

0 голосов
/ 12 февраля 2020

Я бы использовал функцию RANK ()

SELECT   t.first_name, t.count FROM
 (
   SELECT
   first_name, COUNT(1) AS count,
   RANK () OVER (  ORDER BY COUNT(1) DESC ) rank_no 
   FROM USERS_FAKE
   GROUP BY first_name
 ) AS t
 WHERE rank_no = 1
0 голосов
/ 12 февраля 2020
SELECT n.first
FROM names n
JOIN ( SELECT first, COUNT(*) AS cnt
       FROM names
       GROUP BY first
     ) n1 ON ( n1.first = n.first )
ORDER BY n1.cnt DESC group by n.first;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...