3

私は2つのテーブルを持っています-object_72194_そしてobject_72197_それぞれ:

| attr_72195_ |     | attr_72198_ | attr_72199_  |
| 2013-07-31  |     |   a         | 2013-07-31   |
| 2013-07-30  |     |   b         | 2013-07-31   |
| 2013-07-29  |     |   c         | 2013-07-30   |
| 2013-07-28  |     |   d         | 2013-07-29   |

最初のテーブルの各行についてattr_72198_、2 番目のテーブルからフィールドの値を取得したいと考えていattr_72199_ますattr_72195_。したがって、この場合、結果は次のようになります。

|attr_72195_  | attr_72196_  |
|2013-07-31   | a            |
|2013-07-30   | c            |
|2013-07-29   | d            |
|2013-07-28   | NULL         | 

行ごとに値を取得したい。今、私の作業クエリは次のようになります。

SELECT f1.attr_72195_, t.attr_72198_ AS attr_72196_ 
FROM object_72194_ f1 
LEFT OUTER JOIN ( 
 SELECT id, attr_72198_, attr_72199_ FROM object_72197_ t 
) AS t ON t.attr_72199_ <= f1.attr_72195_ 
WHERE ( f1.id_obj = 72194 ) AND (t.attr_72199_ = (
 SELECT MAX(attr_72199_) FROM object_72197_ t 
 WHERE attr_72199_ <= f1.attr_72195_
) OR t.attr_72199_ IS NULL

) ORDER BY f1.id_order DESC

期待どおりに動作します。WHEREしかし、最後のブロックにサブクエリがあるため、最適とは言えません。あるプログラマーは、代わりにグループ化を使用してもう 1 つの結合を使用するようにアドバイスしましたが、方法がわかりません。ありがとうございました!

編集: サブクエリ内の不要な順序付けを削除し、両方のクエリ (私のものと、サブクエリの代わりに結合を使用) をチェックし、興味深い結果を得ました。EXPLAIN は、サブクエリのあるバージョンでは 5 行、結合のあるバージョン (id 列) では 4 行を返しました。「行」列では、サブクエリ バージョンで 13 行、結合バージョンで合計 18 行を取得しました。したがって、使用するバージョンを決定するには、大量のデータを確認する必要があります。

編集:ああ、結合を使用したこのクエリは、列ごとに結果をグループ化するため、正しくないことが判明しました

編集:質問はまだ開いています。問題は、2 番目のテーブルに重複がある場合に発生します。その結果、両方のクエリは、2 番目のテーブルと同じ数の行を返します。しかし、行ごとに値が必要です。値 "a"、"b"、"c"、"d" の例で最初から示したように。

編集:最後に、私はそれをしました。最初のテーブルに一意のフィールドによるグループ化を追加し、前のグループ化を返しました。したがって、クエリは次のようになります。

SELECT f1.attr_72195_, f2.attr_72198_ AS attr_72196_ 
FROM object_72194_ f1
INNER JOIN 
(
 SELECT f1.attr_72195_, MAX(f2.attr_72199_) AS attr_72199_
 FROM object_72194_ f1 
 LEFT OUTER JOIN object_72197_ f2 ON f1.attr_72195_ >= f2.attr_72199_
 GROUP BY f1.attr_72195_
) o
ON f1.attr_72195_ = o.attr_72195_
LEFT OUTER JOIN object_72197_ f2 ON f2.attr_72199_ = o.attr_72199_
GROUP BY f1.id, attr_72195_ ORDER BY f1.id_order DESC

シンプルでエレガント。

4

1 に答える 1

2

相関サブクエリの回避 (テストされていません):-

SELECT f1.attr_72195_, MIN(f2.attr_72198_)
FROM object_72194_ f1
INNER JOIN 
(
    SELECT f1.attr_72195_, MAX(f2.attr_72199_) As Max_attr_72199_
    FROM object_72194_ f1 
    LEFT OUTER JOIN object_72197_ f2
    ON f1.attr_72195_ >= f2.attr_72199_
    GROUP BY f1.attr_72195_
) Sub1
ON f1.attr_72195_ = Sub1.attr_72195_
LEFT OUTER JOIN object_72197_ f2
ON f2.attr_72199_ = Sub1.Max_attr_72199_
GROUP BY f1.attr_72195_

2 つのテーブル間で LEFT JOIN を実行し、最初のテーブル以下の最大日付を 2 番目のテーブルから取得します。その結果を1番目のテーブルに内部結合し、2番目のテーブルに左結合します。日付が重複している場合に必要な attr_72198_ の値がわからないため、min 関数を使用して最小のものを取得しました。

編集

最初のテーブルの重複に対処する必要があるこれを試してください。

SELECT f1.attr_72195_, f2.attr_72198_
FROM object_72194_ f1
INNER JOIN 
(
    SELECT f1.attr_72195_, MAX(f2.attr_72199_) As Max_attr_72199_
    FROM object_72194_ f1 
    LEFT OUTER JOIN object_72197_ f2
    ON f1.attr_72195_ >= f2.attr_72199_
    GROUP BY f1.attr_72195_
) Sub1
ON f1.attr_72195_ = Sub1.attr_72195_
LEFT OUTER JOIN 
(
    SELECT attr_72199_, MIN(attr_72198_) AS attr_72198_
    FROM object_72197_ 
    GROUP BY attr_72199_
) f2
ON f2.attr_72199_ = Sub1.Max_attr_72199_
于 2013-07-17T12:53:42.007 に答える