Набор данных ограничения SQL - PullRequest
0 голосов
/ 27 марта 2019

У меня есть набор данных, который ежедневно обновляется по запросу. Сначала запрос извлекает 11 различных дат из БД на основе комбинации временных рамок конца месяца (каждый конец месяца, который не является указанным временным интервалом) и указанных временных рамок (конец текущего месяца, конец предыдущего месяца, конец текущего квартала, предыдущий квартал конец и т. д.).

Проблема, с которой я сталкиваюсь, заключается в том, что в январе / апреле / ​​июле / октябре и феврале / мае / августе / ноябре мы видим, как в запросе поступают повторяющиеся даты. Т.е. в середине января текущий конец месяца будет декабрь, а текущий конец квартала - декабрь. Или в середине февраля текущий «конец предыдущего месяца» и «конец текущего квартала» будут декабрьскими.

Это вызывает проблемы агрегации вниз по течению в Таблице.

Созданная таблица даты выглядит следующим образом:

Period    Period_Selection
12/31/18  Current Quarter End
12/31/18  Prior Month End
1/31/19   Current Month End
9/30/18   Prior Quarter End

Что я хотел бы сделать, это написать оператор case или where, который ограничивает таблицу данных единственным экземпляром каждой даты. Эти случаи будут конкретными, поэтому они будут влиять на пары: «конец текущего месяца» и «конец текущего квартала» или «конец предыдущего месяца» и «конец текущего квартала». в вышеприведенном примере предложение увидит, что есть два примера '12/31/18', а затем отбросит / проигнорирует один из экземпляров, например, удалит «конец предыдущего месяца» и сохранит «текущий конец квартала».

Пример SQL:

SELECT PERIOD_DATE, PERIOD_SELECTION
FROM db.PERIOD_PROMPT
WHERE db_ORDER_NO IN ( '60000000', '50000000', '40000000')-- 50.. = Current Quarter end, 60.. = current month end, 40.. = prior month end

UNION ALL

SELECT ADD_MONTHS(PERIOD_DT, -3) AS PERIOD_DATE
, 'Prior Quarter End' AS PERIOD_SELECTION
FROM db.PERIOD_PROMPT 
WHERE db_ORDER_NO IN (50000000) --CURRENT QUARTER END

1 Ответ

0 голосов
/ 27 марта 2019

Если вы хотите одну строку для каждого PERIOD_DATE, то вы, вероятно, хотите GROUP BY PERIOD_DATE.Если вам все равно, какой PERIOD_SELECTION выбран, то вы можете просто выбрать агрегатную функцию, чтобы выбрать для вас.Здесь я использую MAX, чтобы выбрать PERIOD_SELECTION, который идет последним в алфавитном порядке («Конец предыдущего месяца», в данном случае).

-- sample data
with period_prompt as (select to_date('12/31/18', 'mm/dd/yy') as period_dt, 'Current Quarter End' as period_selection, 50000000 as db_order_no from dual
                       union all 
                       select to_date('12/31/18', 'mm/dd/yy') as period_dt, 'Prior Month End' as period_selection, 40000000 as db_order_no from dual)
select period_date, 
    max(period_selection) as period_selection
from ( -- your query
    SELECT PERIOD_DT as PERIOD_DATE, PERIOD_SELECTION
    FROM PERIOD_PROMPT
    WHERE db_ORDER_NO IN ( '60000000', '50000000', '40000000')-- 50.. = Current Quarter end, 60.. = current month end, 40.. = prior month end
    UNION ALL
    SELECT ADD_MONTHS(PERIOD_DT, -3) AS PERIOD_DATE
    , 'Prior Quarter End' AS PERIOD_SELECTION
    FROM PERIOD_PROMPT 
    WHERE db_ORDER_NO IN (50000000) --CURRENT QUARTER END
    )
group by period_date;

Но если у вас есть мнения о , какой конкретный PERIOD_SELECTION должно отображаться, вам нужно их заказать - придумайте алгоритм сортировки.Иногда есть естественный выбор - как, может быть, вы хотите PERIOD_SELECTION с самым высоким DB_ORDER_NO.Но в этом случае я не уверен, что у вас есть хороший столбец для сортировки, поэтому мы создадим его.

В этом примере я добавляю столбец PRIORITY и настраиваю еготак что db_order_no, равный 50000000 (конец текущего квартала), имеет приоритет 2, а все остальное имеет значение 1. Затем мы вызываем MAX (period_selection), но указываем, что мы хотим, чтобы запись period_selection имела самый высокий priority.

with period_prompt as (select to_date('12/31/18', 'mm/dd/yy') as period_dt, 'Current Quarter End' as period_selection, 50000000 as db_order_no from dual
                       union all 
                       select to_date('12/31/18', 'mm/dd/yy') as period_dt, 'Prior Month End' as period_selection, 40000000 as db_order_no from dual)
select period_date, 
    max(period_selection) keep (dense_rank first order by priority desc) as period_selection
from (
    SELECT PERIOD_DT PERIOD_DATE, PERIOD_SELECTION, 
        case db_order_no
            when 50000000 then 2
            else 1
        end as priority
    FROM PERIOD_PROMPT
    WHERE db_ORDER_NO IN ( '60000000', '50000000', '40000000')-- 50.. = Current Quarter end, 60.. = current month end, 40.. = prior month end
    UNION ALL
    SELECT ADD_MONTHS(PERIOD_DT, -3) AS PERIOD_DATE
    , 'Prior Quarter End' AS PERIOD_SELECTION
    , 1 as priority
    FROM PERIOD_PROMPT 
    WHERE db_ORDER_NO IN (50000000) --CURRENT QUARTER END
    )
group by period_date;

Вывод:

PERIOD_DATE PERIOD_SELECTION   
----------- -------------------
30-SEP-18   Prior Quarter End  
31-DEC-18   Current Quarter End
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...