1

各スケジュールには多くのランプがあり、各ランプにはend_date.

ランプの ID とそのスケジュールの最新の終了日を含む追加フィールドとともに、すべてのランプを一覧表示する必要があります。WHEREまた、節でこの追加フィールドを使用できるようにする必要があります。

これは通常、MAX関数を使用するサブクエリのケースですが、1 つの問題を除いて、ランプのend_dateフィールドが null になる可能性があり、ランプが現在のものであることを示します。したがって、値は null 以外の値よりも「小さい」SELECT MAX(end_date)ため、機能しません。null

これまでのところ、これは私が思いついたものです:

SELECT r1.*,
    (SELECT r2.id
    FROM ramp as r2
    WHERE schedule_id = r.schedule_id
    ORDER BY IF(end_dte is NULL, '9999-99-99', end_dte) DESC
    LIMIT 1) as latestId
FROM ramp as r1

これにより、まさに私が欲しいものであるこのテーブルが生成されます。

+-------+-------------+------------+-----------------+--------+------------+------------+----------+
| id    | schedule_id | suppr_flag | comment         | months | start_dte  | end_dte    | latestId |
+-------+-------------+------------+-----------------+--------+------------+------------+----------+
|    16 |           7 | NULL       | NULL            |   NULL | 2008-06-23 | NULL       |       16 |
|    15 |           6 | NULL       | NULL            |   NULL | 2007-05-01 | 2007-12-31 |       15 |
|    13 |           5 | NULL       | 1-15 deals      |   NULL | 2004-08-11 | NULL       |       13 |
|    11 |           4 | NULL       | NULL            |   NULL | 2005-08-11 | NULL       |       11 |
|    12 |           4 | NULL       | NULL            |     12 | 2004-08-11 | 2005-08-10 |       11 |
|    17 |          13 | NULL       | NULL            |      6 | 2009-03-05 | 2009-09-04 |       19 |
|    18 |          13 | NULL       | NULL            |      6 | 2009-09-05 | 2010-03-04 |       19 |
|    19 |          13 | NULL       | NULL            |   NULL | 2010-03-05 | NULL       |       19 |
|    20 |          14 | NULL       | NULL            |     12 | 2001-06-18 | 2008-06-17 |       20 |

ただしlatestId、WHERE 句では使用できません (不明な列です)。

あなたはなにか考えはありますか?

4

2 に答える 2

2

簡単な解決策は、ORDER BY 句でクエリ全体を繰り返すことです。そこにはエイリアスが表示されないためですが、クエリがどのように見えるかはあまり好きではありません。

SELECT r1.*,
    (SELECT r2.id
    FROM ramp as r2
    WHERE schedule_id = r1.schedule_id
    ORDER BY IF(end_dte is NULL, '9999-99-99', end_dte) DESC
    LIMIT 1) as latestId
FROM ramp as r1
ORDER BY
    (SELECT r2.id
    FROM ramp as r2
    WHERE schedule_id = r1.schedule_id
    ORDER BY IF(end_dte is NULL, '9999-99-99', end_dte) DESC
    LIMIT 1);

または、元のクエリから SELECT して、結果を並べ替えることができます。

SELECT s.*
FROM (
  SELECT r1.*,
      (SELECT r2.id
      FROM ramp as r2
      WHERE schedule_id = r1.schedule_id
      ORDER BY IF(end_dte is NULL, '9999-99-99', end_dte) DESC
      LIMIT 1) as latestId
  FROM ramp as r1
) s
ORDER BY s.latestId

しかし、あなたのロジックの正しさを理解していれば、このクエリを使用しend_dteてすべての最大値を取得できschedule_idます。

SELECT schedule_id, MAX(COALESCE(end_dte, '9999-12-31')) max_dte
FROM ramp
GROUP BY schedule_id;

次に、このクエリをランプで再度結合して、最大値に関連付けられた ID を取得できますend_dte。ON 句では、COALESCE を再度使用する必要があります。

SELECT r1.schedule_id, r2.id as latestId
FROM (
  SELECT schedule_id, MAX(COALESCE(end_dte, '9999-12-31')) max_dte
  FROM ramp
  GROUP BY schedule_id) r1 INNER JOIN
  ramp r2
  ON r1.max_dte = COALESCE(r2.end_dte, '9999-12-31')
     AND r1.schedule_id = r2.schedule_id

そして、これを再び結合して、必要な結果を得ることができます。

SELECT ramp.*, m.latestId
FROM
  ramp INNER JOIN (
    SELECT r1.schedule_id, r2.id as latestId
    FROM (
      SELECT schedule_id, MAX(COALESCE(end_dte, '9999-12-31')) max_dte
      FROM ramp
      GROUP BY schedule_id) r1 INNER JOIN
      ramp r2
      ON r1.max_dte = COALESCE(r2.end_dte, '9999-12-31')
         AND r1.schedule_id = r2.schedule_id
      ) m ON ramp.schedule_id = m.schedule_id
ORDER BY
  latestId

ここでフィドルを参照してください。「9999-99-99」ではなく「9999-12-31」を使用していることに注意してください。最初の日付は有効な日付ですが、2 番目の日付は無効です。

編集

複数がschedule_id同じ最大日付を共有しているという事実も考慮したい場合、この場合は最新 (最大) ID だけが必要な場合は、GROUP BY クエリと MAX 集計関数を使用できます。

SELECT r1.schedule_id, MAX(r2.id) as latestId
FROM (
  SELECT schedule_id, MAX(COALESCE(end_dte, '9999-12-31')) max_dte
  FROM ramp
  GROUP BY schedule_id) r1 INNER JOIN
  ramp r2
  ON r1.max_dte = COALESCE(r2.end_dte, '9999-12-31')
     AND r1.schedule_id = r2.schedule_id
GROUP BY
  r1.schedule_id

この更新されたバージョンをメイン クエリで使用します。

于 2013-04-02T18:50:13.707 に答える
0

順序で2つの列を使用できます...最初はnull以外の表示フラグ用で、次に日付ごとです。持っていたものを変える...

ORDER BY IF(end_dte is NULL, '9999-99-99', end_dte) DESC

ORDER BY
   IF( end_dte is null, 1, 2 ),
   end_dte DESC

このようにして、すべての「NULL」終了日をリストの一番上にプッシュします (IF() を介して、日付がある他のものについては値が 1 対 2 になります)、その後、日付の降順で

于 2013-04-02T19:17:21.687 に答える