Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выборка последних данных, MySQL 
V
    Опции темы
Мешок
Дата 22.5.2013, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 18.4.2008

Репутация: нет
Всего: нет



Есть таблица Recipients
id, id_mail, email, status (ИД, ИД письма, email, статус получения);
1, 1, '[email protected]', 'error';
2, 1, '[email protected]', 'error';

3, 2, '[email protected]', 'success';
4, 2, '[email protected]', 'error';

5, 3, '[email protected]', 'success';
6, 3, '[email protected]', 'error';

7, 4, '[email protected]', 'error';
8, 4, '[email protected]', 'error';

Нужно выбрать пользователей, которые последние 3 раза не получили письмо, т.е. status='error' должно быть в 4, 3 и 2-й рассылке 
PM MAIL   Вверх
Arantir
Дата 22.5.2013, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: нет
Всего: 55



Код

... WHERE id_mail IN(2,3,4) ...



--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
Мешок
Дата 22.5.2013, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 18.4.2008

Репутация: нет
Всего: нет



Ну это я для примера привел.
А на практике id_mail может быть и более 1 000 000 и не обязательно могут идти по порядку.
PM MAIL   Вверх
boevik
Дата 22.5.2013, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: нет
Всего: 35



Какая СУБД?
Где в таблице пользователь? Это email?


--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
Мешок
Дата 22.5.2013, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 18.4.2008

Репутация: нет
Всего: нет



СУБД: MySQL
Пользователь - email
Проблему уже решил с помощью 2-х запросов.
Но был бы признателен, если бы подсказали, как решить с помощью одного.
PM MAIL   Вверх
boevik
Дата 22.5.2013, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1452
Регистрация: 31.5.2004
Где: Израиль

Репутация: нет
Всего: 35



  могу подсказать решение для MSSQL, может наведет на мысль:
Код

select email 
from (
select row_number (partition by email order by id desc) r, * from table
where r <= 3) t1
where status = 'error'
group by email
having count(*) = 3



--------------------
Никогда не говори никогда
PM MAIL WWW   Вверх
Zloxa
Дата 22.5.2013, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Задача вами не достаточно четко сформулирована и имеет более одного решения, каждое из которых имеет определенные ньюансы и как следствие - шанс быть не правильным. 
Цитата(Мешок @  22.5.2013,  02:19 Найти цитируемый пост)
выбрать пользователей, которые последние 3 раза не получили письмо, т.е. status='error' должно быть в 4, 3 и 2-й рассылке  

1)Начнем с того, что не понятно что такое "пользователи". Я правильно полагаю что пользователи идентифицируются емайлами?
2)Что должно в конце концов отобраться - то, что имеет статус error для каждой из трех последних попыток, или же достаточно чтобы этот статус был у одной из последних трех попыток?
3)Количество попыок для каждого "пользователя" - свое? 
   3.а) если ответ на предыдущий вопрос "нет" -  существует ли обособленный справочник попыток, с id_mail в качестве первичного ключа?
   3.б) если ответ на предыдущий вопрос "нет" - может ли так статься что стока с id = 8 отсутствует, и если да, то что означает ее отсутствие - должны ли мы идентифицировать отсутствие строки как успешную попытку или же должны интерпретировать как ошибку?

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

Цитата(Мешок @  22.5.2013,  13:55 Найти цитируемый пост)
Проблему уже решил с помощью 2-х запросов.

Покажите что-ли эти два запроса

Добавлено через 5 минут и 27 секунд
Цитата(boevik @  22.5.2013,  14:36 Найти цитируемый пост)
select row_number (partition by email order by id desc) r, * from table
where r <= 3

Так разве можно? В смысле использовать аллиас присвоенный в селект-листе в конструкции where.
Дело в том, что where применяется до того как считаются статистические функци.
Или у MS тут особенность какая?

Скорее всего тут просто надо еще один уровень подзапроса ввести.

Добавлено через 8 минут и 33 секунды
Цитата(boevik @  22.5.2013,  14:36 Найти цитируемый пост)
order by id desc

ранжироваться надо, я так полагаю по id_mail

Хотя, конечно это вопрос к ТС - 4)что определяет порядок для вычисления критерия "последние три раза"


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Zloxa
Дата 22.5.2013, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(boevik @  22.5.2013,  14:36 Найти цитируемый пост)
MSSQL

На оракле можно обойтись без группировки, определив окно для ранжирующей функции в две строки помимо текущей и каким нибудь образом посчитав все ли там значения error
Например - так
Код

select * from (
  select 
    email
    ,id_mail
    ,row_number() over (partition by email order by id_mail desc) rn
    ,max(status) over (partition by email order by id_mail desc rows between current row and 2 following) st
  from recipients
)
where rn = 1 and st = 'error'  

здесь я исхожу из того что 'success' болше чем 'error' и  вслучае, если одна из трех последних записей примет это значение, мною будет полученно именно оно

Это сообщение отредактировал(а) Zloxa - 22.5.2013, 14:21


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 22.5.2013, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454





--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Мешок
Дата 22.5.2013, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 18.4.2008

Репутация: нет
Всего: нет



Zloxa
1) Правильно
2) все 3 раза, я ж написал, вроде, понятно: последние 3 раза.
3) 
    а) нет
    б) Если строка отсутствует, то понимаем ее как status !='error' не обязательно это 'success'.

P.S. Всем спасибо! Вопрос решен.
Оставил в 2 запроса
1.
Код

SELECT id_mail FROM Recipients GROUP BY id_mail ORDER BY id_mail DESC LIMIT 3

2.
Код

SELECT *, COUNT(*) as cnt FROM Recipients WHERE id_emailing IN (ид с первого запроса) AND status='error'
GROUP BY email
HAVING cnt=3

Пока оставлю так. Может вечером передалаю в один запрос с помощью переменных:
Цитата(Akina @  22.5.2013,  15:14 Найти цитируемый пост)
Выборка нескольких последних записей в неких группах 


PM MAIL   Вверх
Zloxa
Дата 22.5.2013, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Мешок @  22.5.2013,  16:55 Найти цитируемый пост)
Оставил в 2 запроса

собсна в скобочки вместо "ид с первого запроса" подставьте текст самого запроса и будет у вас один запрос

Добавлено через 1 минуту и 16 секунд
Цитата(Мешок @  22.5.2013,  16:55 Найти цитируемый пост)
 Может вечером передалаю в один запрос с помощью переменных:

На сколько я понимаю это имело бы смысл, если бы на третий вопрос ответ был "да"


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 22.5.2013, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



Цитата(Мешок @  22.5.2013,  16:55 Найти цитируемый пост)
Может вечером передалаю в один запрос с помощью переменных:

Обязательно оттестируйте на реальной БД. ОБычно запросы на переменных сравнительно медленные.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Мешок
Дата 22.5.2013, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 18.4.2008

Репутация: нет
Всего: нет



Zloxa, В MySQL в подзапросе не работает LIMIT - выдается ошибка, а мне нужно только 3 последних.

Akina, если медленнее, тогда, думаю, нет смысла переделывать в 1 запрос. Хотя, для сравнения можно попробовать оба варианта и выбрать лучший.
PM MAIL   Вверх
Zloxa
Дата 22.5.2013, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Мешок @  22.5.2013,  17:30 Найти цитируемый пост)
Хотя, для сравнения можно попробовать оба варианта и выбрать лучший. 

Т.е. это не разовый запрос, вы это решение готовите в продакшн?

Дело в том, что оба способа достаточно плохи ибо требуют полного сканирования набора данных. С ростом объема будет существенно возрастать количество ресурсов необходимых для выполнения этой операции и, возможно, когда-нибудь это количество ресурсов превысит разумное значение.

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


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Arantir
Дата 22.5.2013, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: нет
Всего: 55



Если уж так, то может лучше вообще ввести отдельный счетчик для фейлов? Что-то же записывает в БД error либо success. Вот в том же месте делать +1 при error и обнуление при success. Получается таблица с чисто количеством последних фейлов.
Хоть это и может показаться кривоватым решением, но 
Цитата(Мешок @  22.5.2013,  00:32 Найти цитируемый пост)
А на практике id_mail может быть и более 1 000 000 и не обязательно могут идти по порядку
запись и чтение одной цифры побыстрее будет работать, чем выборка с этих логов.

Кстати, таблица не содержит никаких подробностей, ни даты, ни примечаний... В чем ее смысл? В чем польза знать только лишь успешность всех миллионов отправленных писем?
Почему бы не оставлять столько последний, сколько нужно (например, те же 3), как говорит Zloxa?


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0975 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.