2013-07-25 2 views
1

У меня есть таблица, в которой хранятся действия. Есть два специальных типа действий, скажем, например, «Просыпайтесь» и «Идите спать».Ссылка и рассчитать данные по тому же запросу

Все действия МЕЖДУ «Просыпаться» и «Идут спать» должны возвращать дополнительное поле со значением «AWAKE». Если действие происходит до «Просыпаться» или после «Ложитесь спать», оно должно вернуть дополнительное поле со значением «ASLEEP». (Это только примеры значений, постарайтесь не принимать их слишком серьезно.)

+--------+-----------+ 
| ac_id | ac_name | 
+--------+-----------+ 
| 1  | Talk | 
+--------+-----------+ 
| 2  | Wake Up | 
+--------+-----------+ 
| 3  | Walk | 
+--------+-----------+ 
| 4  | Go to bed | 
+--------+-----------+ 
| 5  | Scream | 
+--------+-----------+ 

С этой структурой, если сделать запрос с SELECT ac_name, ac_status FROM actions_table WHERE ac_name = 'Walk' он должен вернуть:

ac_name: Walk 
ac_status: AWAKE 

... потому что " Walk "находится между" Wake Up "и" Go to bed ".

Мой вопрос в том, как в том же запросе и без каких-либо дополнительных запросов я могу вернуть это значение в зависимости от «позиции» строки?

Возможно, я слишком много требую от MySQL, но если я могу это сделать, я хотел бы знать, как это сделать. Если это невозможно в одном запросе, также будут приняты меры или ФУНКЦИИ.

EDIT В таблице может быть более одного «Wake Up» и более одного «Go to bed».

ответ

1

Вы можете попробовать что-то вроде этого:

SELECT ac_name, 'AWAKE' as ac_status 
FROM actions_table 
WHERE ac_id > (SELECT ac_id FROM actions_table WHERE ac_name = 'Wake Up') AND 
    ac_id < (SELECT ac_id FROM actions_table WHERE ac_name = 'Go to bed') 
UNION 
SELECT ac_name, 'ASLEEP' as ac_status 
FROM actions_table 
WHERE ac_id < (SELECT ac_id FROM actions_table WHERE ac_name = 'Wake Up') OR 
    ac_id > (SELECT ac_id FROM actions_table WHERE ac_name = 'Go to bed' 

Результаты:

ac_name | ac_status 
_________|___________ 
Scream | ASLEEP 
Talk  | ASLEEP 
Walk  | AWAKE 

EDIT:

Может быть это еще одно для одного результата:

SELECT ac_name, 
CASE 
WHEN ac_id > (SELECT ac_id FROM actions_table 
        WHERE ac_name = 'Wake Up') AND 
    ac_id < (SELECT ac_id FROM actions_table 
      WHERE ac_name = 'Go to bed') 
THEN 'AWAKE' 
WHEN ac_id < (SELECT ac_id FROM actions_table 
        WHERE ac_name = 'Wake Up') OR 
    ac_id > (SELECT ac_id FROM actions_table 
      WHERE ac_name = 'Go to bed') 
THEN 'ASLEEP' 
ELSE 'NO STATUS' END as ac_status 
FROM actions_table 
WHERE ac_name = 'Walk' 
+0

Большое спасибо за ответ! Думаю, это должно быть так. Тем не менее - я отредактировал вопрос - может быть, есть более одного «Wake Up» и более одного «Go to bed», поэтому ссылки на ac_id могут вернуть более одного результата. Во всяком случае, я постараюсь сыграть с вашим ответом, чтобы понять. Большое спасибо! – Unapedra

0

Мое предложение создать таблицу ac_status_master с полями ac_name и соответствующим именем ac_. Затем вы можете сделать простое соединение, чтобы получить желаемый результат.

+--------+-----------+ 
| ac_name| ac_status | 
+--------+-----------+ 
| awake | Talk | 
+--------+-----------+ 
| awake | Wake Up | 
+--------+-----------+ 
| awake | Walk | 
+--------+-----------+ 
| asleep | Go to bed | 
+--------+-----------+ 
| asleep | Scream | 
+--------+-----------+ 
+0

Спасибо за ваш ответ. Это допустимое решение, но здесь этот случай очень упрощен. Фактически, я хотел получить способ, чтобы иметь возможность применить его в моем реальном случае, когда структура базы данных намного сложнее. Выполнение, как вы предполагаете, будет означать, что каждый раз, когда я меняю позицию действия (скажем, я хочу поставить «Прогулка» после «Ложитесь спать»), мне придется обновить все связанные таблицы. Однако, еще раз спасибо за ваш ответ! – Unapedra

Смежные вопросы