#sql #oracle #case
#sql #Oracle #случай
Вопрос:
У меня есть файл Excel с таблицей, которая выглядит следующим образом:
A B C
Registry ID Parent Reg ID Focus Account (Y/N)
100000033 100000036778 Y
100000343 1000 Y
1000343223 100000036778 N
И формула находится в столбце D (родительский фокус): =IF(COUNTIFS(C:C,"Y",B:B,B)>=1,"Y","N")
Итак, в столбце D формула возвращает ‘Y’ для каждой строки.
Я попытался реплицировать это в SQL с помощью следующего кода:
SELECT
REGISTRY_ID,
PARENT_REG_ID,
FOCUS_ACCOUNT,
SCORE_DETAILS,
(CASE
WHEN FOCUS_ACCOUNT = 'Y' THEN
(CASE
WHEN COUNT(PARENT_REG_ID) >= 1 THEN 'Y'
ELSE 'N'
END)
ELSE 'N'
END) AS Focus_Parent
FROM MA_ACCOUNTS
Но этот запрос возвращает эту ошибку:
ORA-00937: не является групповой функцией для одной группы
Можете ли вы, пожалуйста, посоветовать?
Последующее редактирование:
Позвольте мне прояснить это: у меня есть список с уникальными идентификаторами REGISTRY_ID, которые содержат Parent_Registry_ID. Parent_Registry_ID может содержать несколько Registry_ID, но если Registry_ID помечен как ‘Y’ в столбце Focus_Account, то этот Parent_Registry_ID должен содержать ‘Y’ в столбце Focus_Parent.
Registry ID Parent Reg ID Focus Account (Y/N)
1 A N
2 B N
3 A Y
4 C Y
5 A N
6 B Y
7 A N
8 D Y
9 E N
10 E N
Ожидаемый результат:
Registry ID Parent Reg ID Focus Account (Y/N) Focus Parent (Y/N)
1 A N Y
2 B N Y
3 A Y Y
4 C Y Y
5 A N Y
6 B Y Y
7 A N Y
8 D Y Y
9 E N N
10 E N N
Комментарии:
1. поделитесь ожидаемым результатом
2. Вы используете
COUNT(PARENT_REG_ID)
вSELECT
, поэтому ожидаетеGROUP BY
Ответ №1:
Вы используете агрегированный, count()
поэтому Oracle ожидает предложение GROUP BY. Однако это не соответствовало бы форме вашего результирующего набора. Кажется, аналитическая функция была бы лучше?
Вы опубликовали разъяснение, которое, я думаю, определяет это правило:
если какая-либо
registry_id
имеетfocus_account='Y'
значение, то установитеfocus_parent = 'Y'
для всех ее экземпляровparent_reg_id
.
Если моя интерпретация верна, вы можете довольно просто реализовать ее с помощью аналитического max()
:
select
registry_id,
parent_reg_id,
focus_account,
max( focus_account ) over (partition by parent_reg_id) as focus_parent
from ma_accounts
Это работает, потому что focus_account
это флаг Y / N. Конечно, приведенный выше запрос выдает ваш пересмотренный набор результатов на основе опубликованных входных данных.
Комментарии:
1. Это работает! Я также обнаружил, что этот код также работает:
SELECT M.*,NVL(x.FOCUS_ACCOUNT,'N') FROM MA_ACCOUNTS M LEFT JOIN (SELECT DISTINCT PARENT_REG_ID, FOCUS_ACCOUNT FROM MA_ACCOUNTS WHERE FOCUS_ACCOUNT = 'Y') X ON X.PARENT_REG_ID = M.PARENT_REG_ID
Спасибо за ваш ответ!2. Пожалуйста. Часто мы обнаруживаем, что указание четкого требования является ключом к получению своевременного и полезного решения: D
Ответ №2:
Вы используете агрегированный метод в разделе выбора, но не группируете в конце для других выбранных переменных.
Попробуйте:
SELECT
REGISTRY_ID,
PARENT_REG_ID,
FOCUS_ACCOUNT,
SCORE_DETAILS,
CASE WHEN COUNT(PARENT_REG_ID) >= 1 AND FOCUS_ACCOUNT = 'Y' THEN 'Y'
ELSE 'N' END AS Focus_Parent
FROM MA_ACCOUNTS
GROUP BY REGISTRY_ID,
PARENT_REG_ID,
FOCUS_ACCOUNT,
SCORE_DETAILS
Комментарии:
1. Группировка по всем столбцам в проекции изменит вычисление
focus_parent
. Версия Excel учитывает вхождения всегоPARENT_REG_ID
.