11

MySqlデータベースのテーブルに対してクエリを実行する必要があります。結果の行の順序は次のようになります。

今日が10/09/12の場合:

...
11/09/12 
12/09/12
15/09/12
08/09/12  <--here start the past dates
07/09/12
05/09/12
....

MySQLでこれを直接達成する方法はありますか?


私はこのように解決しました:

まず、selectステートメントには、日付が過去か未来かを示す新しいブール値が含まれています。

SELECT DISTINCT *,CASE  WHEN startdate < CURDATE() THEN 0
                ELSE 1 END AS past_or_future 

次に、二重の「順序付け」を実行しました。最初はpast_or_futureブール値で、次に日付で、次のような条件を使用します。

ORDER BY past_or_future  DESC , CASE WHEN past_or_future  = 1 THEN startdate END ASC, CASE WHEN past = 0 THEN startdate END DESC

このようにして、最初に日付順に並べられたすべての今後の日付(低い値から高い方へ)を取得し、次に日付から並べ替えられたすべての過去の日付(高い方から低い方へ)を取得しました。

4

3 に答える 3

16

文節でCASEもステートメントを実行できますが、ORDER BY

SELECT *
FROM tableName
ORDER BY (CASE WHEN DATE(dateColumn) < DATE(GETDATE())
              THEN 1
              ELSE 0
         END) DESC, dateColumn ASC
于 2012-09-11T08:01:00.297 に答える
4

はい、1 つの方法は、「より強力な」ソート キーを使用して 2 つのクエリを結合することです (以下の列名ではなく位置を使用しています)。

select 1 as uberkey, date1, column2
  from mytable
  where data1 >= '2012-10-09'
union all
select 2 as uberkey, date1, column2
  from mytable
  where data1 < '2012-10-09'
order by 1 asc, 2 asc

これにより、 を主要な並べ替えフィールドとして使用しuberkeyて、後の日付が最初になるようにします。データを表示するときは、この列を単純に無視できます。

これは多くの場合、行ごとに変換を行う必要があるcaseため、行ごとの関数よりも効率的です。case句を含む 2 つのクエリでは、where単にインデックスを使用して行の残りの「半分」を破棄し、取得した行に定数を使用できます。

そして (私は MySQL について特別な知識はありませんが、私自身 DB2 の人間です) インテリジェントな DBMS は、クエリの 2 つのサブコンポーネントを効率的に並列化できます。

すべてのユニオンと同様に、2 つのサブコンポーネントが相互に排他的である場合は必ず使用してくださいunion all。これにより、不要な並べ替えと重複の削除操作が不要になります。

于 2012-09-11T08:04:42.983 に答える
0

通常、UNION を使用しないと、1 つの列を両方向にソートすることはできません。特にORMを使用している場合、UNIONにはいくつかの欠点があります。今後のASCで過去のDESCを注文したい場合は、トリックでそれを行うことができます:

SELECT yourDateColumn,IF(yourDateColumn)

ORM で使用することもでき、ページネーターなども使用できます。

于 2014-04-16T10:31:35.067 に答える