Фильтрация результатов CTE, чтобы в конечном итоге попасть в отчет SQL

#sql #sql-server #tsql #subquery #common-table-expression

#sql #sql-server #tsql #подзапрос #common-table-expression

Вопрос:

Я работаю с SSMS, SQL Server и SSRS. У меня есть результаты в CTE, которые я хочу отфильтровать дальше «после» его запуска.

Запрос ищет несколько записей идентификаторов в таблице. Затем он выбирает те, которые имеют нулевые значения. Это правильный выбор, и мне нужно еще больше сузить область.

На данный момент я бы в прошлом сбрасывал выходные данные этого в файл Excel, искал и выделял повторяющиеся значения в поле ID и показывал только эти строки. Моя цель — включить это в отчет SSRS.

Нужно ли мне просто создать представление, а затем запустить против него другое представление CTE, какой-то тип вложенного запроса или сохранить процедуру и отфильтровать результаты или использовать пользовательскую функцию? Могу ли я использовать что-то вроде запятой после первого CTE и, возможно, выполнить еще один оператор WITH? Заранее спасибо.

 WITH T AS
(
SELECT [ID] ,
    [LOCATION] ,
    [LOCATION_START_DATE],
    [LOCATION_END_DATE],
    [POS],
    COUNT(*) OVER (PARTITION BY [ID]) as Cnt
FROM LOCATIONS_TABLE WITH (NOLOCK)
)
SELECT  [ID] ,
    [LOCATION] ,
    [LOCATION_START_DATE],
    [LOCATION_END_DATE],
    [POS]
FROM T
WHERE Cnt >= 2
AND LOCATION_END_DATE IS NULL
ORDER BY ID
  

Комментарии:

1. Ваш вопрос станет намного понятнее с образцами данных и ожидаемыми результатами.

Ответ №1:

Вы можете каскадировать несколько CTE следующим образом:

 WITH 
    T AS (
        SELECT [ID] ,
            [LOCATION] ,
            [LOCATION_START_DATE],
            [LOCATION_END_DATE],
            [POS],
            COUNT(*) OVER (PARTITION BY [ID]) as Cnt
        FROM LOCATIONS_TABLE WITH (NOLOCK)
    ),
    U AS (
        SELECT  [ID] ,
            [LOCATION] ,
            [LOCATION_START_DATE],
            [LOCATION_END_DATE],
            [POS]
        FROM T
        WHERE Cnt >= 2
        AND LOCATION_END_DATE IS NULL
    )
SELECT ...
  

Комментарии:

1. Вы даже можете присоединиться к ранее каскадному cte (если вам это нужно по какой-либо причине)

2. Спасибо. Это сработало отлично после того, как я исправил некоторые из своих синтаксических ошибок. Ценю это.

Ответ №2:

Вы можете создать локальную #temporary_table, вставить результаты CTE в эту #temporary_table и отфильтровать результаты в виде выборки, сохранив их в файл по своему усмотрению.

Преимущество этого подхода заключается в том, что #temporary_tables намного быстрее, чем вложенные запросы и обычные таблицы. Еще одним преимуществом является то, что вы можете создавать другие запросы, которые создают другие фильтры в #temporary_table, которые менее сложны, чем вложенные CTE, и позволяют создавать другие отчеты без изменения CTE всякий раз, когда вам нужен новый фильтр.

Локальную временную таблицу можно создать так же, как и обычную таблицу.

 CREATE TABLE #temporary_table_name(
-- fields that match the results of the CTE
);
  

Вы можете вставлять записи во временную таблицу так же, как и в обычную таблицу.

 INSERT INTO #temporary_table_name.
  

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

Надеюсь, это помогло вам!

Комментарии:

1. Спасибо за предложение. Я сохраню временные таблицы в may toolkit на потом. Ценю помощь.