Попытка реплицировать функцию ‘= countifs’ из Excel в SQL

#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 .