![]() |
Модераторы: skyboy |
![]() ![]() ![]() |
|
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: нет Всего: 74 |
Привет, друзья! Помогите пожалуйста составить запрос для следующей задачи:
Предположим, есть таблица, и ней три рабочих столбца - "Время", "Пользователь" и "Последнее действие" Пользователь - он и есть пользователь, время ставится триггером при добавлении записи в таблицу, а Последнее действие может принимать два значения: "подписался" и "отписался" (subscribe & unsubscribe). Очевидно, что пользователь может сперва подписаться, потом отписаться, потом снова подписаться и снова отписаться. И нужно узнать список всех пользователей, которые на данный момент подписаны. Например, данные в таблице(дял простоты время цифрами по порядку): 1 Вася подписался 2 Миша подписался 3 Витя подписался 4 Витя отписался 5 Миша отписаля 6 Витя подписался В результате запроса мне нужно получить подписанных сейчас: Васю и Витю. Как проверить статус одного конкретного пользователя я догадался: SELECT Пользователь FROM Activities WHERE Последнее действие="подписался" AND Пользователь=Витя ORDER BY Время LIMIT 1 и увидеть, подписан сейчас Витя или нет. (Может быть я забыл DESC...) А как проделать такое с громадной таблицей и получить именно список всех подписанных на данный момент. PS Прошу не предлагать варианта SELECT Пользователь FROM Activities WHERE Последнее действие="подписался" Потому что задача не предполагает хранение по одному экземпляру пользователя и переустанове ему свойства "Последнее действие". Именно добавление каждого нового действия новой строкой. Такая штука нужна для разработки потоковой шины над базой данных. Заранее спасибо! -------------------- Всем добра ![]() |
|||
|
||||
Gluttton |
|
|||
![]() Начинающий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1170 Регистрация: 28.8.2008 Где: Феодосия Репутация: 24 Всего: 54 |
SoWa, а можно выбрать максимальное время с группировкой по пользователям получив при этом последнее действие каждого пользователя, а затем в WHERE выбрать тех, у которых "подписался"? Или я не внимательно читал задание
![]() -------------------- Слава Україні! |
|||
|
||||
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: нет Всего: 74 |
А это как?
![]() Меня максимальное время настораживает - в таблицу постоянно сыплются новые записи... Если это чем-то поможет пониманию :( Добавлено через 1 минуту и 14 секунд Если бы я знал, что такое "с группировкой", то конечно, в конце подписать WHERE = ... и дело в шляпе. Но я не знаю, что за группировка ( -------------------- Всем добра ![]() |
|||
|
||||
Gluttton |
|
||||
![]() Начинающий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1170 Регистрация: 28.8.2008 Где: Феодосия Репутация: 24 Всего: 54 |
Безусловно такой запрос будет не из быстрых, т.к., если я не ошибаюсь, то для поиска максимального элемента должна будет выполнена сортировка и на больших объемах данных этот вариант не годится. Но! при существующей постановке задачи мне кажется, что приемлимого решения нет и необходимо вводить дополнительные решения ну там флаги какие нибудь, там тригеры или ещё чего-нибудь... Например можно сделать отдельную таблицу с одной единственной записью состояний всех пользователей и поставить триггер на вставку данных. При этом выбирать данные будет очень просто, но зато вставка в таблицу будет происходить медленнее... Поправил запрос - добавил user в select. И не WHERE, а HAVING - я был не прав. Это сообщение отредактировал(а) Gluttton - 26.7.2011, 19:14 -------------------- Слава Україні! |
||||
|
|||||
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: нет Всего: 74 |
Ой, спасибо огромное! Сейчас MS SQL поставится - буду проверять
![]() Разумеется, это медленное решение, как архитектор я это понимаю, и конечно буду оптимизировать. А пока моя задача - накидать приемлимо-понятный код на известном мне языке(C#) и показать завтра ребятам, чтобы они уже начинали делать рабочую версию со всеми прибамбасами. -------------------- Всем добра ![]() |
|||
|
||||
solenko |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1473 Регистрация: 15.1.2006 Где: Украина Репутация: 4 Всего: 67 |
код некорректный. Некоторый СУБД будут плеваться на смешение в запросе агретных функций а некоторые просто выдавать случайные данные для user_action. Оптимальный вариант (можно сказать стандарт) для решения такой задачи: 1. Форматируем дату так, чтобы она правильно сортировалась в строковом виде, например, YYYYMMDDHIS 2. Присоединяем српава интересуэщую нас колонку со статусом (user_action) 3. группируем по id пользователя и выбираем MAX получившейся колонки 4. В select разделяем статус и дату (проблемы не составляет, т.к. блинна даты точно известна) Второй вариант join таблици самой на себя, но он существенно тормознутее Добавлено через 1 минуту и 58 секунд Кстати, раз уж используете триггеры, то почему не денормализировать данные и не хранить _актуальный_ статус для каждого пользователя? -------------------- Ла-ла-ла-ла Заметьте, нет официального подтверждения, что это не просто четыре слога. |
||||
|
|||||
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: нет Всего: 74 |
Я не знаком с понятием присоединение справа, группировками и прочими. Мне просто нужен запросик, вот и все :( Невозможно что-то приписывать пользователям в нашей задаче. Централизованное хранилище пользователей находится не в этой таблице - это первое. Второе - модель данных системы предполагает, что пользователь может быть подписан на один тип данных и не подписан на другой. Т.е. пользователи у нас(а быть точнее - у нас нет такого понятия вообще - есть Source) болванки с какими-то данными, никак не относящимися к потоку. -------------------- Всем добра ![]() |
|||
|
||||
solenko |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1473 Регистрация: 15.1.2006 Где: Украина Репутация: 4 Всего: 67 |
А я не знаком с ms sql. Для mysql будет примерно так:
-------------------- Ла-ла-ла-ла Заметьте, нет официального подтверждения, что это не просто четыре слога. |
||||
|
|||||
Gluttton |
|
|||
![]() Начинающий ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1170 Регистрация: 28.8.2008 Где: Феодосия Репутация: 24 Всего: 54 |
Незачто! Судя по всему преждевременно ;) . solenko, Да, действительно код не валидный. Не мне кажеться, что "кнопка" должна где то быть ;) . -------------------- Слава Україні! |
|||
|
||||
Zloxa |
|
||||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Яхуууу ![]() Какая версия? если 2005 аnd over
-------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
||||
|
|||||
SoWa |
|
|||
![]() Харекришна ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2422 Регистрация: 18.10.2004 Репутация: нет Всего: 74 |
А что такое s?
Добавлено через 2 минуты и 25 секунд Извиняюсь, не важно что такое s - главное, что это сработало!!! -------------------- Всем добра ![]() |
|||
|
||||
Zloxa |
|
|||
![]() Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 53 Всего: 161 |
Прсевдоним набора данных. Предназначен для разрешения конфликта имен. MS SQL обязует псевдонимить подзапросы. Даже там, где конфликтов быть не может ![]() -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка ![]() |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Составление SQL-запросов | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |