1

这是我在较大 SQL 脚本中的子查询。它在多个不同的 CASE 语句中执行相同的操作,所以我希望我可以以某种方式组合该操作,这样它就不必一遍又一遍地做同样的事情。但是,如果我将 ORDER BY 命令移到 CASE 语句之外,我将无法获得正确的结果。

我在 JDAY 加入了 2 个表,met_data 和 flexgridlayers_table。Flexgridlayers_table 具有 JDAY 和 Segment 的字段,met_data 具有 JDAY、TAIR 和 TDEW 字段(在这个简单的示例中,但实际上有更多字段)。我通过 Matlab 运行它,所以variable1variable2是由嵌套循环设置的值。我需要使用 CASE 语句来说明variable1不等于 1 的情况,然后我想输出 0。否则,我想找到与 JDAY 连接对应的值,但这些值可能与 F 中的值不完全匹配。 JDAY 和 M.JDAY。我想匹配最接近的 <= 值,所以我在每个子查询中使用 ORDER BY M.JDAY DESC LIMIT 1 语句。

输出是一个包含字段 JDAY(来自 F.JDAY)、TAIR 和 TDEW 的表。每当我尝试将 ORDER BY 部分移到 CASE 语句之外以摆脱重复的子查询时,我只会得到代表最大 JDAY 的单行结果。这个查询给了我正确的结果 - 有没有办法优化它?

SELECT F.JDAY, 
    CASE
        WHEN *variable1*<>1 THEN 0 
        ELSE 
            (SELECT M.TAIR 
            FROM met_data AS M
            WHERE M.Year=2000 AND M.JDAY<=F.JDAY
            ORDER BY M.JDAY DESC LIMIT 1)
    END AS TAIR,
    CASE
        WHEN *variable1*<>1 THEN 0 
        ELSE                
            (SELECT M.TDEW 
            FROM met_data AS M
            WHERE M.Year=2000 AND M.JDAY<=F.JDAY
            ORDER BY M.JDAY DESC LIMIT 1)
    END AS TDEW
FROM FlexGridLayers_table AS F
WHERE F.SEGMENT=*variable2*

进一步说明:

此查询从 flexgridlayers_table 中提取所有 JDAY 值,然后在表 met_data 中搜索以查找与该表中最接近的 <= JDAY 值对应的值。例如,考虑以下 flexgridlayers_table 和 met_data 表:

flexgridlayers_table:
Segment  JDAY
2        1.5
2        2.5
2        3.5
3        1.5
3        2.5
3        3.5

met_data:
JDAY  Year  TAIR  TDEW
1.0   2000  7     8
1.1   2000  9     10
1.6   2000  11    12
2.5   2000  13    14
2.6   2000  15    16
3.4   2000  17    18
4.0   2000  19    20

对于variable1 =1和variable2 =2,我想要的(以及上面的查询返回的)是这样的:

JDAY  TAIR  TDEW
1.5   9     10
2.5   13    14
3.5   17    18  

我只是想知道是否有更有效的方法来编写此查询,因此我不会对每个 TAIR、TDEW 等字段的同一 JDAY 值列表一遍又一遍地执行 ORDER BY 命令。

4

1 回答 1

2

然后我会写如下......看起来你正在寻找每个 JDAY 的“TAIR”和“TDEW”。如果是这种情况,请在年份条件和 F 与 M JDay 值上将 LEFT JOIN 应用于您的met_data 表。现在通常,这将在每个“JDay”返回多行

SELECT 
      PQ.JDay,
      PQ.MaxJDayPerFDay,
      CASE WHEN *var1* <> 1 THEN 0 ELSE M2.TAIR END TAIR,
      CASE WEHN *var1* <> 1 THEN 0 ELSE M2.TDEW END TDEW
   from 
      ( SELECT 
              F.JDay,
              MAX( M.JDAY ) as MaxJDayPerFDay
           from 
              FlexGridLayers_Table F
                 JOIN met_Data M
                    ON M.Year = 2000
                    AND F.JDay >= M.JDay
           where
              F.Segment = *var2* 
           group by
              F.JDay ) PQ 
         JOIN Met_Data M2 
            on M2.Year = 2000 
            AND PQ.MaxJDayPerFDay = M2.JDay

现在,它通过在met_data ONCE 中应用MAX() JDay 并按JDay 分组来进行预查询,因此它总是每个F.JDay 返回一条记录。因此,现在您有一个预限定为您的 F.Segment = 变量 2 的查询。如果您想要从“F”表中获得其他列,请根据需要将它们放入此“PreQuery”(PQ 别名)。

然后,可以立即将此结果连接回met_data 表,因为现在可以从预查询中明确知道一天的值。因此,您现在可以一次获取 TAIR 和 TDEW 值,而不是针对每条记录应用两个单独的查询。

希望这是有道理的,如果没有,请告诉我。

于 2012-11-14T02:57:58.223 回答