| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Составление SQL-запросов > Запрос завязанных на времени данных |
| Автор: SoWa 26.7.2011, 18:23 |
| Привет, друзья! Помогите пожалуйста составить запрос для следующей задачи: Предположим, есть таблица, и ней три рабочих столбца - "Время", "Пользователь" и "Последнее действие" Пользователь - он и есть пользователь, время ставится триггером при добавлении записи в таблицу, а Последнее действие может принимать два значения: "подписался" и "отписался" (subscribe & unsubscribe). Очевидно, что пользователь может сперва подписаться, потом отписаться, потом снова подписаться и снова отписаться. И нужно узнать список всех пользователей, которые на данный момент подписаны. Например, данные в таблице(дял простоты время цифрами по порядку): 1 Вася подписался 2 Миша подписался 3 Витя подписался 4 Витя отписался 5 Миша отписаля 6 Витя подписался В результате запроса мне нужно получить подписанных сейчас: Васю и Витю. Как проверить статус одного конкретного пользователя я догадался: SELECT Пользователь FROM Activities WHERE Последнее действие="подписался" AND Пользователь=Витя ORDER BY Время LIMIT 1 и увидеть, подписан сейчас Витя или нет. (Может быть я забыл DESC...) А как проделать такое с громадной таблицей и получить именно список всех подписанных на данный момент. PS Прошу не предлагать варианта SELECT Пользователь FROM Activities WHERE Последнее действие="подписался" Потому что задача не предполагает хранение по одному экземпляру пользователя и переустанове ему свойства "Последнее действие". Именно добавление каждого нового действия новой строкой. Такая штука нужна для разработки потоковой шины над базой данных. Заранее спасибо! |
| Автор: Gluttton 26.7.2011, 18:41 |
| SoWa, а можно выбрать максимальное время с группировкой по пользователям получив при этом последнее действие каждого пользователя, а затем в WHERE выбрать тех, у которых "подписался"? Или я не внимательно читал задание |
| Автор: SoWa 26.7.2011, 19:04 |
| А это как? Меня максимальное время настораживает - в таблицу постоянно сыплются новые записи... Если это чем-то поможет пониманию :( Добавлено через 1 минуту и 14 секунд Если бы я знал, что такое "с группировкой", то конечно, в конце подписать WHERE = ... и дело в шляпе. Но я не знаю, что за группировка ( |
| Автор: SoWa 26.7.2011, 19:19 |
| Ой, спасибо огромное! Сейчас MS SQL поставится - буду проверять Разумеется, это медленное решение, как архитектор я это понимаю, и конечно буду оптимизировать. А пока моя задача - накидать приемлимо-понятный код на известном мне языке(C#) и показать завтра ребятам, чтобы они уже начинали делать рабочую версию со всеми прибамбасами. |
| Автор: solenko 26.7.2011, 19:47 | ||||
код некорректный. Некоторый СУБД будут плеваться на смешение в запросе агретных функций а некоторые просто выдавать случайные данные для user_action. Оптимальный вариант (можно сказать стандарт) для решения такой задачи: 1. Форматируем дату так, чтобы она правильно сортировалась в строковом виде, например, YYYYMMDDHIS 2. Присоединяем српава интересуэщую нас колонку со статусом (user_action) 3. группируем по id пользователя и выбираем MAX получившейся колонки 4. В select разделяем статус и дату (проблемы не составляет, т.к. блинна даты точно известна) Второй вариант join таблици самой на себя, но он существенно тормознутее Добавлено через 1 минуту и 58 секунд Кстати, раз уж используете триггеры, то почему не денормализировать данные и не хранить _актуальный_ статус для каждого пользователя? |
| Автор: SoWa 26.7.2011, 20:05 | ||
Я не знаком с понятием присоединение справа, группировками и прочими. Мне просто нужен запросик, вот и все :( Невозможно что-то приписывать пользователям в нашей задаче. Централизованное хранилище пользователей находится не в этой таблице - это первое. Второе - модель данных системы предполагает, что пользователь может быть подписан на один тип данных и не подписан на другой. Т.е. пользователи у нас(а быть точнее - у нас нет такого понятия вообще - есть Source) болванки с какими-то данными, никак не относящимися к потоку. |
| Автор: solenko 26.7.2011, 20:22 | ||||
А я не знаком с ms sql. Для mysql будет примерно так:
|
| Автор: Gluttton 26.7.2011, 22:16 |
Незачто! Судя по всему преждевременно ;) . solenko, Да, действительно код не валидный. Не мне кажеться, что "кнопка" должна где то быть ;) . |
| Автор: Zloxa 26.7.2011, 22:48 | ||||
Яхуууу Какая версия? если 2005 аnd over
|
| Автор: SoWa 27.7.2011, 06:24 |
| А что такое s? Добавлено через 2 минуты и 25 секунд Извиняюсь, не важно что такое s - главное, что это сработало!!! |
| Автор: Zloxa 27.7.2011, 07:28 |
Прсевдоним набора данных. Предназначен для разрешения конфликта имен. MS SQL обязует псевдонимить подзапросы. Даже там, где конфликтов быть не может |