Как сортировать при использовании оператора UNION в Oracle SQL. Я использую два оператора select и оператор UNION, я хочу отсортировать результаты обоих запросов.

Я пытаюсь решить HackerRank SQL - вопрос PADS.

Вопрос в том:

Сгенерируйте следующие два набора результатов:

  1. Запросите упорядоченный по алфавиту список всех имен в ПРОФЕССИЯХ, сразу за которыми следует первая буква каждой профессии в скобках (т. е. заключенная в круглые скобки). Например: AnActorName(A), ADoctorName(D), AProfessorName(P) и ASingerName(S).

  2. Запросите количество вхождений каждой профессии в OCCUPATIONS. Отсортируйте вхождения в порядке возрастания и выведите их в следующем формате:

    There are a total of [occupation_count] [occupation]s.
    
    

    где [occupation_count] — количество вхождений профессии в ПРОФЕССИИ, а [occupation] — название профессии в нижнем регистре. Если несколько профессий имеют одинаковые [occupation_count], их следует расположить в алфавитном порядке.

Мое решение:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM OCCUPATIONS
ORDER BY NAME 
UNION  
SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION 
ORDER BY OCCUPATION;

OP:
ERROR at line 4:
ORA-00933: SQL command not properly ended
(It seems, we cannot use ORDER BY BEFORE UNION)

Я пересмотрел свой код на:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM OCCUPATIONS 
UNION  
SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION 
ORDER BY NAME, OCCUPATION;

OP:
ERROR at line 7:
ORA-00904: "NAME": invalid identifier

Пожалуйста, помогите мне здесь.

В общем (для всех, кто хочет знать, как упорядочить результаты UNION/INTERSECT/MINUS, вам нужно будет следовать ключевым словам order by с одним или несколькими именами столбцов из верхнего списка select (в вашем случае есть только один столбец , поэтому order by NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' , но вы также можете присвоить ему псевдоним и упорядочить по имени псевдонима), или еще один или несколько позиционных идентификаторов, относящихся к n-му столбцу, например, order by 1 для упорядочения по первому столбцу в списке select.

William Robertson 12.11.2022 17:12
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
1
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку вы хотите вывести два упорядоченных набора данных в одном запросе, самый простой способ - назначить идентификатор каждому запросу, а затем упорядочить его и столбец, который вы хотите упорядочить, например:

SELECT info
FROM   (SELECT 1 qry, NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' info
        FROM   OCCUPATIONS
        UNION ALL
        SELECT 2 qry, 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' info
        FROM OCCUPATIONS
        GROUP BY OCCUPATION)
ORDER BY qry, info;

Обратите внимание, что, поскольку два запроса не будут возвращать одни и те же строки, я использовал UNION ALL, поскольку UNION выполняет DISTINCT для результирующего набора данных, а UNION ALL — нет. Кроме того, я предполагаю, что если у вас есть два разных человека с одинаковым именем и профессией (например, разные даты рождения), вы должны вывести обе строки, а не одну строку?

Также обратите внимание, что когда у вас есть запрос UNION/UNION ALL, выходные столбцы наследуют имя столбца из первого запроса, поэтому ваш второй запрос выдавал вам ошибку недопустимого идентификатора (вы не дали своему столбцу псевдоним!).

Эй .. он работает нормально, спасибо за решение и объяснение. Кроме того, нужно научиться использовать идентификатор и разницу между UNION и UNION ALL :)

Janvi C 11.11.2022 10:56

Я ответил на ваш вопрос о том, как упорядочить запросы UNION, но я должен сказать, что MT0 полностью верен в том смысле, что ваше решение не отвечает на вопрос, который вы отправили из hackerrank, который требует двух наборов результатов. И порядок второго запроса нуждается в настройке

Boneist 11.11.2022 12:18

Сгенерируйте следующие два набора результатов

Вы НЕ генерируете два набора результатов. Вы выполняете два SELECT и пытаетесь объединить их в один набор результатов, используя UNION, и это не то, о чем просит вопрос. Прекратите использовать UNION и используйте два запроса.

Первый результирующий набор будет таким:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM   OCCUPATIONS 
ORDER BY NAME;

Второй результирующий набор будет:

SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' || LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION

а затем вам нужно ORDER BY количество вхождений И затем название профессии (которое я оставляю вам решить).

Ага... также получил вывод, используя два отдельных запроса. Спасибо! КОД: ВЫБЕРИТЕ ИМЯ || '(' || SUBSTR(OCCUPATION,1,1) || ')' FROM OCUPATION ORDER BY NAME; SELECT 'Всего ' || СЧЁТ(ПРОФЕССИЯ) || ' ' || НИЖЕ(ПРОФЕССИЯ) || 'с.' ИНФОРМАЦИЯ ОТ ПРОФЕССИЙ ГРУППА ПО ЗАНЯТИЯМ ПОРЯДОК ПО ИНФОРМАЦИИ;

Janvi C 11.11.2022 11:19

@JanviChitroda Последнее предложение ORDER BY неверно, поскольку в вопросе вас просят «Отсортировать вхождения в порядке возрастания ... [и], если несколько профессий имеют одинаковое количество занятий, они должны быть упорядочены в алфавитном порядке». Вы сортируете вхождения в алфавитном порядке (как часть строки info), а не в возрастающем числовом порядке, и вы не включаете занятие в предложение порядка.

MT0 11.11.2022 11:24

Я сортирую строку INFO (например: всего 3 врача, всего 4 актера). Здесь начало строки (всего ) будет одинаковым для всех записей, поэтому он будет проверять наличие количество профессий и после этого название профессии. Таким образом, он косвенно сортирует 1-е место по количеству профессий, а затем по названию профессии. Я получаю результат от этого, но я не уверен, что метод правильный, поскольку я недавно начал изучать SQL. Пожалуйста, поправьте меня, если подход неверен.

Janvi C 11.11.2022 18:37

@JanviC Если вы сортируете как числа, то 1 < 2 < 12 однако, если вы сортируете как строки, то '1' < '12' < '2'. Вы сортируете по INFO, которая является (сцепленной) строкой, и она будет сортировать занятие с 12 людьми перед занятием с 2 людьми; это НЕ в порядке возрастания количества занятий. Вам нужно сортировать непосредственно по числовому значению COUNT, а не по объединенной строке.

MT0 11.11.2022 20:01

Другие вопросы по теме