Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.140.198.43] |
|
Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Сообщ.
#1
,
|
|
|
Всем привет, есть три таблицы.
Start -------- id int Start_Event DateTime id_Event int End -------- id int End_Event DateTime id_Event int Event -------- id int NameEvent varchar Ситуация может быть таковой что в таблице Start могут занестись две записи начала одного и того же события или на оборот две записи конца одного и того же события в таблицу End. Тогда первую запись события нужно не отображать. select * from start_event s_e left JOIN event e on s_e.id=e.id left JOIN end_event end_e on end_e.id=e.id WHERE NOT EXISTS (SELECT 1 FROM start_event s_e left JOIN event e on s_e.id=e.id left JOIN end_event end_e on end_e.id=e.id WHERE s_e.Start_Event BETWEEN s_e.Start_Event AND end_e.End_Event) А как записать Start_Event следующее время прихода одного и того же события в таблице Start. То есть я хочу создать диапазон начало события и конец и проверить входит следующее время записи в интервал или нет. |
Сообщ.
#2
,
|
|
|
Надо удалить повторяющиеся события или не отображать повтор?
|
Сообщ.
#3
,
|
|
|
Не отображать.
Добавлено Если время события попала в заданный интервал значит не отображать. |
Сообщ.
#4
,
|
|
|
1) Укажите используемую СУБД. В разных диалектах эту задачу нужно решать по-разному, чтобы не ввергнуть сервер в коматозное состояние.
2) Сформулируйте ТОЧНО задачу на построение запроса. Не надо себя дополнять - формулируйте так, словно раньше вообще ничего не говорили. 3) Поясните, почему Вы не хотите удалить заведомо ошибочные записи? |
Сообщ.
#5
,
|
|
|
Здесь не проще сделать group by по id события и времени, округленному например до минуты?
|
Сообщ.
#6
,
|
|
|
Использую Mysql. Есть некое событие, Т1 и Т2 начало и конец некоторого события, начало и конец этого события может зарегистрироваться в базу несколько раз. Удалять повторившееся событие из базы нельзя так как это статистика. Sql запрос это аналитика. Мне нужно отсечь повторяющееся событие начало или конца для того чтобы вычислить интервал события.
|
Сообщ.
#7
,
|
|
|
Тогда самое разумное - это выбирать запросом сразу корректные интервалы. Это можно сделать, например, по такой логике: выбрать из таблиц записи такие, что timestart<timeend, и ни в одной из таблиц нет записи с временем между этими временами. Соответственно это будет выглядеть где-то так:
SELECT t1.Start_Event, t2.End_Event FROM Start t1 INNER JOIN End t2 ON t1.id_Event=t2.id_Event AND t1.Start_Event<t2.End_Event LEFT JOIN Start t3 ON t1.id_Event=t3.id_Event AND t3.Start_Event BETWEEN t1.Start_Event AND t2.End_Event LEFT JOIN END t4 ON t1.id_Event=t4.id_Event AND t4.End_Event BETWEEN t1.Start_Event AND t2.End_Event WHERE t3.id IS NULL AND t4.id IS NULL На большом массиве это будет весьма небыстро, так что настоятельно рекомендую, во-первых, по всем 4 таблицам делать пред-отбор (дополнительные условия отбора в секции ON) для необходимого интервала времени, во-вторых, озаботиться необходимыми индексами. |
Сообщ.
#8
,
|
|
|
А если три или больше повторяющихся событий начала или конца?
|
Сообщ.
#9
,
|
|
|
Да хоть двадцать восемь. Будут выбраны только те начало-конец, между которыми нет записей. Т.е. последнее начало из группы, или первое окончание из группы.
PS. Хуже, если из окончаний тоже надо выбирать последнее. Тогда лучше выполнять "чистку" в подзапросах, и только потом связывать. PPS. Хотя в таком случае можно применить иной подход - искать максимальное время окончания, не превышающее следующее начало. Но это дополнительная группировка, что также скажется на производительности вовсе не лучшим образом. В общем, можетет высказать своё "фэ" тому гению, который "архитекторил" эту схему данных. |
Сообщ.
#10
,
|
|
|
А если бы Start и End были в одной таблице? Это улучшило ситуацию?
|
Сообщ.
#11
,
|
|
|
Я на самом деле разрабатываю систему учета рабочего времени, вместо турникетов будут использовать считыватели. Есть вероятность того что работник несколько раз проведет своей карточкой на входе или на выходе. Я с начала не хотел это рассказывать, но вдруг поможите. Прилагаю схему базы.
Прикреплённый файл________.png (24,75 Кбайт, скачиваний: 404)
|
Сообщ.
#12
,
|
|
|
Цитата Dmitriy78781 @ Я на самом деле разрабатываю систему учета рабочего времени, вместо турникетов будут использовать считыватели. Есть вероятность того что работник несколько раз проведет своей карточкой на входе или на выходе. Стандартно любая СКУД должна настраиваться так, чтобы после входа через точку контроля типа "вход-выход" (в отличие от точки типа "проход") обязательно был выход. Повторная попытка входа должна интерпретироваться как нарушение охранной зоны и блокироваться. Цитата Dmitriy78781 @ А если бы Start и End были в одной таблице? Это улучшило ситуацию? Это было бы правильно с точки зрения нормализации. Есть событие "считывание", а вход или выход - это его атрибуты. |
Сообщ.
#13
,
|
|
|
Тогда в запросе нужно будет определять с какого считывателя пришла информация?
Добавлено А что вы скажите насчет двух выходов? Добавлено Повторные выходы должны блокироваться? |
Сообщ.
#14
,
|
|
|
Я что-то не понимаю... Вы что, свою собственную СКУД с нуля делаете, что ли?
Цитата Dmitriy78781 @ что вы скажите насчет двух выходов? Да то же, что и про вход - попытка выхода без входа должна считаться нарушением и блокироваться. Цитата Dmitriy78781 @ в запросе нужно будет определять с какого считывателя пришла информация? Вообще-то именно номер считывателя определяет, какое произошло событие - попытка входа или попытка выхода. А датчик турникета сообщает, успешна попытка (турникет провернулся, был проход) или нет. |
Сообщ.
#15
,
|
|
|
Цитата Dmitriy78781 @ А что вы скажите насчет двух выходов? Это же не "сферический конь в вакууме", он не может мгновенно переместиться от одного выхода/выхода к другому. Обычно там где вход там и выход (их может быть несколько). id_Readera показывает где произошло событие вход/выход. Akina, правильно заметил, клиент может хоть сто раз провести карточкой но турникет не открылся - событие не произошло. |