Использовать ORDER BY в производной таблице - PullRequest
0 голосов
/ 27 августа 2018

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

Создал следующий запрос на sql-сервере-

select 
    withnull.[Metric Name],
    ISNULL(withnull.[Metric Value], withnullx.[Metric Value]) MetricValue,
    ISNULL(withnull.[Red Threshold], withnullx.[Red Threshold]) Red,
    ISNULL(withnull.[Yellow Threshold], withnullx.[Yellow Threshold]) Yellow,
    withnull.[Date]
from 

    (
    SELECT [Metric Value], [Red Threshold], [Yellow Threshold], Mon.[Date], Mon.[Metric Name]
    FROM

        (
        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['#1 Effectiveness (SPC)$']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['#1 MRB Effectiveness (Non-Conf)$']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['#1 Effectiveness(Problem Solvi)$']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['Calibration Passing "As Found" $']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['Change Control Malfunction Rate$']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['MSA passing rate$']

        UNION ALL

        SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
        FROM [QMS Scorecard].[dbo].['Unknown Failures (FMEA & Ctrl)$']
        ) Data

        RIGHT JOIN

        (
        SELECT [Date], [Metric Name]
        FROM [Dates$]
        --ORDER BY [Metric Name], [Date]
        ) Mon

    ON datepart(mm, Data.[Last Updated Date]) = datepart(mm, Mon.[Date])
    AND
    datepart(yyyy, Data.[Last Updated Date]) = datepart(yyyy, Mon.[Date])
    AND
    Data.[Metric Name] = Mon.[Metric Name]

    --ORDER BY [Metric Name], [Date]
    ) withnull

    outer apply

    (SELECT [Metric Value], [Red Threshold], [Yellow Threshold]
    FROM (SELECT * from (SELECT *, row_number() OVER (PARTITION BY [Metric Name] ORDER BY [Date] DESC) rn from
        (
        SELECT [Metric Value], [Red Threshold], [Yellow Threshold], Mon.[Date], Mon.[Metric Name]
        FROM

            (
            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['#1 Effectiveness (SPC)$']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['#1 MRB Effectiveness (Non-Conf)$']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['#1 Effectiveness(Problem Solvi)$']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['Calibration Passing "As Found" $']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['Change Control Malfunction Rate$']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['MSA passing rate$']

            UNION ALL

            SELECT [Metric Name], [Last Updated Date], [Metric Value], [Red Threshold], [Yellow Threshold]
            FROM [QMS Scorecard].[dbo].['Unknown Failures (FMEA & Ctrl)$']

            ) Data

            RIGHT JOIN

            (
            SELECT [Date], [Metric Name]
            FROM [Dates$]
            ) Mon

        ON datepart(mm, Data.[Last Updated Date]) = datepart(mm, Mon.[Date])
        AND
        datepart(yyyy, Data.[Last Updated Date]) = datepart(yyyy, Mon.[Date])
        AND
        Data.[Metric Name] = Mon.[Metric Name]

        ) b ) d
        WHERE rn = 1) c
    WHERE 
        c.[Date]<withnull.[Date] and 
        withnull.[Metric Value] is null and
        c.[Metric Value] is not null and 
        c.[Red Threshold] is not null and 
        c.[Yellow Threshold] is not null

    ORDER BY [Metric Name], [Date] DESC
    ) withnullx

Я присоединился к рабочему листу для всех метрик, используя UNION ALL, и чтобы у меня было все месяцы для каждого имени метрики, я сделал правильное объединение.

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

С помощью Outer Apply я заменяю эти NULL на значения предыдущего месяца. Для этого требуется ORDER BY во второй последней строке кода выше.

В приведенном выше коде есть еще один Order BY. «SELECT * from (SELECT *, row_number () OVER (PARTITION BY [Имя метрики] ORDER BY [Date] DESC) rn» Это помогает мне получить не только вершину за полные данные, но и вершину за каждое имя метрики.

Я надеюсь, что если бы я мог использовать этот код, я смогу заменить значения NULL на значения предыдущего месяца для каждого имени метрики. Но я получаю сообщение об ошибке: «Предложение ORDER BY недопустимо в представлениях, встроенных функциях, производных таблицах, подзапросах и выражениях общих таблиц, если также не указаны TOP, OFFSET или FOR XML». Заранее спасибо.

1 Ответ

0 голосов
/ 29 августа 2018

Сначала - ошибка говорит вам, в чем проблема, но не объясняет почему. Ваш заказ по пытается отсортировать запрос. Но этот запрос является подзапросом и используется для применения к другой таблице. В этом случае порядок подзапроса совершенно не имеет значения. SQL не заботится о том, каков порядок результатов запроса, чтобы выполнить соединение / применить, и основной порядок запросов устанавливается его собственным предложением порядка. Следовательно, предложение order на самом деле ничего не сделает, даже если SQL позволил вам это сделать и не выдал ошибку.

Я думаю, что вы пытаетесь применить только первый ряд подзапроса? В этом случае вам нужно убедиться, что запрос возвращает только те строки, которые вы хотите применить, или что вы можете указать, какие строки вы хотите. ORDER BY не сделает этого. Вы уже сделали это внутри подзапроса на более раннем этапе, установив rownmuber, а затем, ограничив rownumber 1, я думаю, это будет делать именно то, что вы хотите.

Это то, что ваш подзапрос, который вы применяете в настоящее время, делает

Q1 - Outer query with lots of where stuff (Date < date, Red and yellow not null, etc
   Q2 - Query that only allows most recent row per [Metric Name]
      Q3 - Query that gets data and adds a rownumber by date

Q3 получает данные и сортирует их по дате для каждого имени метрики. Q2 затем выбирает только самую последнюю строку для каждого [имени метрики], все остальные отбрасываются. Q1 затем применяет множество предложений where. Проблема в том, что если предложение where не выполняется, у вас нет других строк для просмотра, потому что вы уже выбросили их в Q2. И предложение where всегда будет неудачным, потому что в самой последней строке никогда не будет даты, которая меньше строки, с которой вы сопоставляете.

Что вам нужно сделать, так это как-то переместить все предложения where, прежде чем вы сделаете бит, где вы вернете только одну строку. Таким образом, вы берете только самую последнюю действительную строку, а не только самую последнюю строку. Вам нужно переместить предложение where в запрос Q3, который содержит row_number. Нулевые пункты будут легко перемещаться, но дату нужно будет переосмыслить.

...