Как получить поле из таблицы дважды (оба на разных условиях)?

#mysql

#mysql

Вопрос:

У меня есть одна таблица под названием Reader с id, датой, временем в качестве полей . Поле time содержит как время поступления, так и время выхода сотрудников, поэтому я хотел бы получить значение, присутствующее во времени дважды, на основе 2 условий для определенного идентификатора и диапазона дат:

 1.In-time:Time between '9:00:00' and '12:00:00'
2.Out-time:Time between '15:00:00' and '19:00:00'
  

Команда должна выглядеть примерно так

 select id,tim,tim,dat from reader 
where tim between '09:00:00' and '14:00:00' 
and   tim between '15:00:00' and '17:00:00' 
and dat between '2011-01-17' and '2011-01-19' 
and id =10704 ;
  

Ответ №1:

Я думаю, что добавление AND r1.dat=r2.dat в код Thilo может быть полезным, если вы хотите сгруппировать входы и выходы за один день в одну строку.

Ответ №2:

 select id,tim,dat from reader 
where ((tim between '09:00:00' and '14:00:00')
    or (tim between '15:00:00' and '17:00:00'))
and dat between '2011-01-17' and '2011-01-19' 
and id =10704 ;
  

Вам нужно ИЛИ между временами, а не И, поскольку время никогда не может находиться в пределах ДВУХ непересекающихся диапазонов. Обязательно заключите эту часть условия в квадратные скобки, иначе ваши И / Или не будут работать должным образом.

Выше приведены данные в отдельных строках. Чтобы получить их одинаковыми для одной и той же записи, вы могли бы использовать, предполагая, что только один раз в каждом диапазоне в день

 select rin.id,rin.tim,rout.tim as timeout,rin.dat
from reader rin
left join reader rout on rout.id=rin.id
    and rout.tim between '15:00:00' and '17:00:00'
    and rin.dat = rout.dat
where rin.tim between '09:00:00' and '14:00:00'
and rin.dat between '2011-01-17' and '2011-01-19' 
and rin.id =10704
union all
select rout.id,rin.tim,rout.tim as timeout,rout.dat
from reader rout
left join reader rin on rout.id=rin.id
    and rin.tim between '09:00:00' and '14:00:00'
    and rin.dat = rout.dat
where rout.tim between '15:00:00' and '17:00:00'
and rout.dat between '2011-01-17' and '2011-01-19' 
and rout.id =10704
and rout.id is null
  

Эта специальная форма UNION ALL эмулирует ПОЛНОЕ ОБЪЕДИНЕНИЕ, которое отсутствует в MySQL. Вы сможете видеть данные, даже когда сотрудник приходит, но не уходит, или уходит, но не входит в любой день.

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

1. Ну, первое дает только одно значение (время), и я не получил ваш второй код …… не могли бы вы дать мне больше информации об этом …. как я уже сказал, у меня есть только 1 поле time …. Запись ч / б 9-12 находится во времени, а 3-7 — вне времени …. мне нужен способ ее получить

Ответ №3:

вы должны быть в состоянии сделать это как-то так: (Я предполагаю, что у вас есть другое поле, предоставляющее информацию о том, находится ли оно внутри или вне. В противном случае вы основываете свой запрос на очень слабом предположении. Однако:

 SELECT r1.id, r1.tim, r2.tim, r1.dat 
FROM reader AS r1, reader AS r2 
WHERE r1.id = 10704 AND r2.id = 10704
    AND r1.tim BETWEEN '09:00:00' AND '14:00:00' 
    AND r2.tim BETWEEN '15:00:00' AND '17:00:00' 
    AND r1.dat BETWEEN '2011-01-17' AND '2011-01-19';
  

Обратите внимание, что я поставил условие для идентификатора в самом верху, предполагая, что оно является наиболее ограничительным и, таким образом, возможно, немного повышает производительность (что в хороших случаях оптимизатор запросов может сделать сам)

Приветствую Thilo

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

1. у меня нет никакого другого поля, указывающего, входит оно в таблицу или нет, и у меня нет двух таблиц reader, у меня есть только 1

2. Мой приведенный выше код обходится без специального поля. Все, что я хотел сказать этим, в основном сводится к вопросу: что, если я уже ухожу в 13.55? Однако мой запрос не предполагает, что у вас есть две разные таблицы. Вы дважды запрашиваете (одно и то же!) средство чтения таблиц и просто объединяете все строки вместе — посмотрите теорию объединений, если вы не знакомы с этим. После этого мы отфильтровываем все строки, которые соответствуют условиям, которые мы хотим отфильтровать. Комментарий Рояса, тем не менее, действителен.

3. Тогда здесь считается хорошим тоном принять ответ (нажав галочку слева на ответ, который вам помог).