簡體   English   中英

在子查詢中使用按個案排序

[英]Using an order by case in a sub-query

每個時間表都有許多坡度,並且每個坡度都有一個end_date

我需要列出所有坡道,以及一個額外的字段,其中包含坡道的ID和該計划的最新結束日期。 我還需要能夠在我的WHERE子句中使用此額外字段。

對於使用MAX函數的子查詢,通常是這種情況,除了一個問題:斜坡的end_date字段可以為null,表示斜坡是當前的。 因此, SELECT MAX(end_date)不起作用,因為null值比非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 |

除非我不能在WHERE子句中使用latestId (這是一個未知列)。

你有什么想法?

一種快速的解決方案是在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

但是,如果我了解您的邏輯正確性,則可以使用此查詢來獲取每個schedule_id的最大end_dte

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

然后,您可以再次使用ramp聯接此查詢,以獲取與最大end_dte關聯的ID。 在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-12-31”,而不是“ 9999-99-99”,第一個是有效日期,第二個不是有效日期。

編輯

如果您還希望考慮一個以上的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

並在主查詢中使用此更新版本。

您可以按順序使用兩列...首先是非空指示標志,然后是日期。 改變你擁有的...

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 vs 2),然后按日期降序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM