SQL: УПОРЯДОЧИТЬ ПО `дате` И НАЧАТЬ С `value’=»что-то»?

#mysql #sql

#mysql #sql

Вопрос:

Таблица SQL:

 -----------------------------------------
| ID  |   COLOR   |         DATE        |
|-----|-----------|---------------------|
|  1  | ORANGE    | 2011-11-03 01:14:00 |
|  2  | YELLOW    | 2011-11-03 01:13:00 |
|  3  | GREEN     | 2011-11-03 01:16:00 |
|  4  | BLUE      | 2011-11-03 01:16:00 |
|  5  | PINK      | 2011-11-03 01:12:00 |
-----------------------------------------
  

Следующий запрос дает мне результаты, упорядоченные по дате:

 SELECT *
FROM `table`
ORDER BY `date` DESC
LIMIT 0, 4

-----------------------------------------
| RESULT:                               |
|---------------------------------------|
|  3  | GREEN     | 2011-11-03 01:16:00 |
|  4  | BLUE      | 2011-11-03 01:16:00 |
|  1  | ORANGE    | 2011-11-03 01:14:00 |
|  2  | YELLOW    | 2011-11-03 01:13:00 |
-----------------------------------------
  

Но что, если я захочу упорядочить его по дате, а также начать с определенного «цвета»?

 SELECT *
FROM `table`
ORDER BY `date` DESC
LIMIT 0, 4
START WHERE `color`='blue'

-----------------------------------------
| RESULT I WANT:                        |
|---------------------------------------|
|  4  | BLUE      | 2011-11-03 01:16:00 |
|  1  | ORANGE    | 2011-11-03 01:14:00 |
|  2  | YELLOW    | 2011-11-03 01:13:00 |
|  5  | PINK      | 2011-11-03 01:12:00 |
-----------------------------------------
  

^ Каков правильный синтаксис для получения этого результата?

Ответ №1:

 SELECT 
  y.*
FROM
  YourTable y
WHERE
  y.date <= (SELECT yb.date FROM YourTable yb WHERE yb.color = 'BLUE')
ORDER BY
  y.date DESC
LIMIT 4 OFFSET 0
  

Обновлено:

 SELECT 
  y.*
FROM
  YourTable y
WHERE
  /* The colors 'before' blue */
  y.date < (SELECT yb.date FROM YourTable yb WHERE yb.color = 'BLUE') or
  /* And blue itself */
  y.color = 'BLUE'
ORDER BY
  y.date DESC
LIMIT 4 OFFSET 0
  

Второе обновление для соответствия вновь обнаруженным критериям.

 SELECT 
  y.*
FROM
  YourTable y,
  (SELECT yb.id, yb.date FROM yb WHERE color = 'GREEN') ys
WHERE
  /* The colors 'before' green */
  y.date < ys.date or
  /* The colors on the same date as green, but with greater 
     or equal id to green. This includes green itself.
     Note the parentheses here. */
  (y.date = ys.date and y.id >= ys.id)
ORDER BY
  y.date DESC
LIMIT 4 OFFSET 0
  

Комментарии:

1. Единственная проблема в том, что если две строки имеют одинаковую дату / время, она не будет начинаться со строки, где color = `BLUE`, она начнется со строки с более низким идентификатором. Есть ли какой-нибудь способ убедиться, что он начинается с определенной строки?

2. Я обновил время в примере, чтобы вы могли видеть, что я говорю.

3. Слегка измененная версия. <= изменяется на < , чтобы получить только цвета с датой до даты СИНЕГО. Второе условие включало сам СИНИЙ цвет, независимо от даты.

4. Одна проблема. Если бы я хотел указать ЗЕЛЕНЫЙ в качестве начального цвета (а не синий), то синий не отображался бы в результатах, хотя синий идет после зеленого в списке.

5. То есть вы имеете в виду, что теперь ИДЕНТИФИКАТОРЫ тоже важны? Вот почему рекомендуется точно указать, какие правила вам нужны. Примеры не приведут вас туда напрямую, потому что они не охватывают все исключения. 🙂