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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сгруппировать с выборкой минимального 
V
    Опции темы
maxipub
Дата 14.4.2016, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Добрый день!

Пишу скрипт на php, но хотелось бы решение вопроса на mysql, поэтому вопрос в этом разделе.

Скрипт получает от пользователя значения data_id, например: 0, 1, 2.

Есть таблица с полями: data_id, value (оба целочисленные, оба не уникальные). Необходимо выбрать одно значение data_id, для которого сумма value будет минимальна. Делаю так:

Код
SELECT data_id FROM table WHERE data_id IN (0, 1, 2) GROUP BY data_id ORDER BY SUM(value) ASC LIMIT 1


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

Как быть? Данные data_id получаем от пользователя, таблицы с ними (чтоб заджойнить) нету, и делать ее под эту задачу не очень хочется. smile 
PM MAIL   Вверх
ksnk
Дата 14.4.2016, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

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



maxipub, Вообще-то работать будет. Ну нету какого то ID, найдетcя другой. Если за параметры отвечает пользователь - он сам и виноват в полученом результате.
Если проблема в валидации данных пользователя, то все тоже несложно
Код

SELECT distinct data_id FROM table WHERE data_id IN (0, 1, 2)

Количество строк ответа должно совпасть с количеством разных параметров


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
maxipub
Дата 14.4.2016, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ksnk, видимо не до конца ясно описал. Суть в том, что данные на входе в запрос валидные 100%, т.е. с ними надо считаться. Если какого-то id нет в таблице, это по сути означает что для него SUM(value) = 0. Вот что нужно.

data_id, value
0, 10
0, 20
2, 30

SELECT с data_id IN (0, 1, 2) в данном случае должен нам вернуть data_id=1, т.к. если так можно сказать, SUM(value) = 0.

Добавлено через 1 минуту и 15 секунд
Если нету такого ID, его SUM(value) считаем = 0. Но этот ID не игнорируем!

Там вообще все value целочисленные, следовательно любой отсутствующий ID - наш потенциальный "клиент". smile

Добавлено через 1 минуту и 59 секунд
Тьфу! "Там вообще все value целочисленные" - не просто целочисленные. а положительные значения, >= 0.
PM MAIL   Вверх
igorold
Дата 14.4.2016, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 557
Регистрация: 22.12.2005
Где: Россия->Урал-& gt;Миасс

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



maxipub, если у вас есть таблица, где хранится уникальный индекс, соответствующий data_id, то вам нужно сделать к этой таблице left join table по этому индексу и будет вам счастье ...

Добавлено через 5 минут и 18 секунд
Вот, пример для моей базы:

Код

select pr.i, min(pc.WorkTimes) from Problems pr left join ProblemsContent pc on pc.ProblemID=pr.i where pr.i in (24831,24760) group by pr.i;


Добавлено через 8 минут и 44 секунды
а, у вас сумма ... ну переделаете на sum() и добавить сортировку и лимит 1


--------------------
... у семи нянек 14 сисек ...  
Putin here, Putin there, Putin almost everywhere!
PM MAIL   Вверх
maxipub
Дата 14.4.2016, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



igorold, 
Цитата(maxipub @  14.4.2016,  13:39 Найти цитируемый пост)
Данные data_id получаем от пользователя, таблицы с ними (чтоб заджойнить) нету, и делать ее под эту задачу не очень хочется.

 smile но за уделенное внимание вопросу, спасибо! smile 
PM MAIL   Вверх
ksnk
Дата 14.4.2016, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

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



Возможно, можно сформировать VIEW со всеми необходимыми параметрами и 0-ми значениями, объединенный с основной таблицей. Потом с этой вьюшкой и делать группировку с суммированием. Хотя, не очень понятно, насколько это будет "неджоин"?


Это сообщение отредактировал(а) ksnk - 14.4.2016, 17:11


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
igorold
Дата 14.4.2016, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 557
Регистрация: 22.12.2005
Где: Россия->Урал-& gt;Миасс

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



а если union использовать? ... утром приду на работу, проверю идею ... 


--------------------
... у семи нянек 14 сисек ...  
Putin here, Putin there, Putin almost everywhere!
PM MAIL   Вверх
Zloxa
Дата 14.4.2016, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(maxipub @  14.4.2016,  14:39 Найти цитируемый пост)
data_id IN (0, 1, 2) 

я правильно понимаю, перечисление в in вы формируете динамически? Если да, наверное, вам не сложно будет сфомрировать и подобное выражение
Код

select 0 data_id from dual union all
select 1 data_id from dual union all
select 2 data_id from dual


ну и, теперь есть с чем сделать внешнее соединение

Код

SELECT s.data_id,  colesce(max(t.value), 0) 
FROM 
(
    select 0 data_id from dual union all
    select 1 data_id from dual union all
    select 2 data_id from dual
) s
left join table t on s.data_id = t.data_id
GROUP BY s.data_id 
ORDER BY  colesce(max(t.value), 0) ASC LIMIT 1



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


Опытный
**


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

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



Цитата(ksnk @  14.4.2016,  17:10 Найти цитируемый пост)
Хотя, не очень понятно, насколько это будет "неджоин"?

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

Цитата(Zloxa @  14.4.2016,  22:31 Найти цитируемый пост)
я правильно понимаю, перечисление в in вы формируете динамически?

Правильно.

Цитата(Zloxa @  14.4.2016,  22:31 Найти цитируемый пост)
from dual

То что надо! Я понимал что надо как-то сформировать параметры "временной таблицы" и заджойнить ее. Идея вертелась, но никогда так не делал. Все не мог догнать как это можно сделать, теперь все понятно!

Почитал еще раз ман, правильно ли я понимаю, что вместо:

Код
select 0 data_id from dual union all
select 1 data_id from dual union all
select 2 data_id from dual


можно написать просто:

Код
select 0 data_id union all
select 1 data_id union all
select 2 data_id


(без from dual) и никаких проблем не будет, одно и то же?
PM MAIL   Вверх
Zloxa
Дата 15.4.2016, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


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

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



Цитата(maxipub @  15.4.2016,  12:10 Найти цитируемый пост)
 правильно ли я понимаю

Полагаю что да, но, как по мне, с from dual прикольнее - читаемее.




--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




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


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

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