在衍生表格中使用ORDER BY

时间:2018-08-27 20:56:41

标签: sql-server-2012 sql-order-by derived-table

我有7个度量标准名称,理想情况下,每个月都应更新所有这些度量标准,但有时不会发生。在这种情况下,我需要结转上个月的指标值,红色阈值和黄色阈值。所有数据均来自Excel。

已经在sql-server-上创建了以下查询-

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加入了所有度量标准的工作表,并且为了每个度量标准名称都花了几个月的时间,我进行了正确的联接。

现在我有几个月的Null值(指标值,红色阈值,黄色阈值),没有这些特定指标名称的记录。

使用外部申请,我将这些NULL替换为上个月的值。这需要在上面代码的第二行中输入ORDER BY。

上面的代码中还有另一个Order BY。 “ SELECT *从(SELECT *,row_number()OVER(按[度量标准名称]排序按[日期] DESC排序)rn” 这不仅使我不仅获得完整数据的顶部,而且也获得了每个指标名称的顶部。

我希望可以使用此代码,我将能够用每个指标名称的前一个月值替换NULL值。但是我收到一个错误消息:“除非指定TOP,OFFSET或FOR XML,否则ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效。”预先谢谢你。

1 个答案:

答案 0 :(得分:0)

首先-该错误告诉您问题出在哪里,但没有解释原因。您的订单依据正在尝试对查询进行排序。但是该查询是一个子查询,用于应用于另一个表。在这种情况下,子查询的顺序完全不相关。 SQL并不关心执行联接/应用的查询结果的顺序,主要查询顺序由其自己的order子句设置。因此,即使SQL允许您这样做并且没有出错,order子句实际上也不会做任何事情。

我认为您要尝试仅应用子查询的第一行?在这种情况下,您需要确保查询仅返回要应用的行,或者可以指定所需的行。 ORDER BY不会这样做。通过设置rownmuber,然后在以后将行号限制为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子句失败,那么您就没有其他要看的行了,因为您已经在第二季度将它们扔掉了。而且where子句始终会失败,因为最近的行永远不会比您要匹配的行的日期短。

您需要做的是以某种方式将所有where子句移至执行仅返回一行的位之前。这样一来,您将只获取最近的有效行,而不仅是最近的行。您需要将where子句移至Q3查询,其中第一个带有row_number。 null子句很容易移动,但必须重新考虑第一个日期。