1

これは、より大きなSQLスクリプトにあるサブクエリです。複数の異なるCASEステートメント内で同じアクションを実行しているので、同じことを何度も繰り返す必要がないように、何らかの方法でアクションを組み合わせることができると期待していました。ただし、ORDER BYコマンドをCASEステートメントの外に移動すると、正しい結果を得ることができません。

JDAYで、met_dataとflexgridlayers_tableの2つのテーブルを結合しています。Flexgridlayers_tableにはJDAYとSegmentのフィールドがあり、met_dataにはフィールドJDAY、TAIR、およびTDEWがあります(この単純な例では、実際にはもっと多くのフィールドがあります)。私はこれをMatlabで実行しているので、variable1variable2はネストされたループによって設定された値です。variable1が1に等しくない状況を説明するために、CASEステートメントを使用する必要があります。次に、0を出力します。それ以外の場合、JDAY結合に対応する値を検索しますが、値はFで完全に一致しない可能性があります。 JDAYとM.JDAY。最も近い<=値に一致させたいので、各サブクエリでORDER BY M.JDAY DESCLIMIT1ステートメントを使用します。

出力は、フィールドJDAY(F.JDAYから)、TAIR、およびTDEWを持つテーブルです。繰り返しのサブクエリを取り除くためにORDERBY部分をCASEステートメントの外に移動しようとすると、最大のJDAYを表す結果が1行だけ表示されます。このクエリは正しい結果をもたらします-これを最適化する方法はありますか?

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値の同じリストに対してORDERBYコマンドを繰り返し実行していません。

4

1 に答える 1

2

それでは、次のように書きます...JDAYごとに1つの「TAIR」と「TDEW」を探しているようです。その場合は、年の条件とF対MのJDay値で1回met_dataテーブルにLEFTJOINを適用します。通常、これは「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ごとに常に1つのレコードが返されます。これで、F.Segment =変数2に対して事前に修飾されたクエリが1つあります。「F」テーブルから必要な他の列がある場合は、必要に応じてそれらをこの「PreQuery」(PQエイリアス)に配置します。

次に、この結果をすぐにmet_dataテーブルに結合して戻すことができます。これは、1日の値がprequeryから明示的にわかっているためです。そのため、レコードごとに2つの個別のクエリを適用するのではなく、TAIR値とTDEW値の両方を一度に取得できるようになりました。

これが理にかなっていることを願っていますが、そうでない場合は、私に知らせてください。

于 2012-11-14T02:57:58.223 に答える