[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: запросы с подсчетом значений
zvezda_t
Скажите пожалуйста, можно ли объединить данные запросы в один? И улучшет ли объединение быстродействие?

select count(*) From table1 where val1=3

select count(*) From table1 where val1=4




Спустя 2 минуты, 27 секунд (25.01.2011 - 17:35) Snus написал(а):
zvezda_t
Если ты эти циферки потом складываешь между собой, то так
SELECT COUNT(*) FROM `table1` WHERE `val1` = '3' OR `val1` = '4'

Спустя 1 минута, 5 секунд (25.01.2011 - 17:36) zvezda_t написал(а):
Snus
нет, мне именно отдельно нужно значения получить.

Спустя 21 секунда (25.01.2011 - 17:37) linker написал(а):
Первое что пришло на ум
(select count(*) From table1 where val1=3)
union
(select count(*) From table1 where val1=4)

Спустя 1 минута, 35 секунд (25.01.2011 - 17:38) linker написал(а):
Или так
select count(*) as count3, (select count(*) From table1 where val1=4) as count4 From table1 where val1=3

Спустя 1 минута, 5 секунд (25.01.2011 - 17:39) sergeiss написал(а):
linker - по-моему, лучше будет так:
select (select count(*) From table1 where val1=3) as count1, (select count(*) From table1 where val1=4) as count2

В этом случае данные выбираются одним запросом.

Спустя 11 секунд (25.01.2011 - 17:39) Snus написал(а):
zvezda_t
Покажи структуру таблицы своей

Спустя 7 минут, 16 секунд (25.01.2011 - 17:47) linker написал(а):
sergeiss
Спорно.

Спустя 3 минуты, 14 секунд (25.01.2011 - 17:50) linker написал(а):
EXPLAIN моего примера дает только один SUBQUERY
EXPLAIN твоего примера дает два SUBQUERY

Вывод очевиден.

Спустя 7 минут, 37 секунд (25.01.2011 - 17:58) sergeiss написал(а):
Цитата (linker @ 25.01.2011 - 18:47)
Спорно.

Смотря что спорно... Считать-то все равно будет одно и то же, реально будет 2 запроса, так что время должно быть более-менее одинаковое smile.gif Но зато мой запрос более наглядный.

И кстати - в Постгре Explain показывает все равно 2 запроса... Не знаю, что там у тебя Мускуль мудрит smile.gif

Спустя 6 минут, 39 секунд (25.01.2011 - 18:04) linker написал(а):
sergeiss
smile.gif В твоем случае реально 3 запроса, один основной и два подзапроса. Время конечно минимально, но собственно, чем меньше тем лучше все же.

Спустя 4 часа, 1 минута, 2 секунды (25.01.2011 - 22:05) kirik написал(а):
А такое не подойдет?
SELECT val1, COUNT(*) FROM table1
WHERE val1 IN(3, 4)
GROUP BY val1

Спустя 2 часа, 7 минут, 49 секунд (26.01.2011 - 00:13) inpost написал(а):
kirik
У меня как раз именно такое стоит для подсчёта, его и хотел предложить =)

Спустя 8 часов, 35 минут, 41 секунда (26.01.2011 - 08:49) zvezda_t написал(а):
kirik, спасибо! :)

В итоге получилась у меня функция

function fun_kv ($dey)
{

$m_kv=array();

$result=mssql_query("Select vid, status, count(*) as kol_vo
from dbo.KVuser where
(dey1<"
.$dey." OR dey1 IS NULL)
and status in (1, 2, 3, 4) and vid in(1,2,3,4,6)
Group by vid, status"
);
while($row=mssql_fetch_array($result))
{
$i=$row['vid'];
$j=$row['status'];
$val=$row['kol_vo'];

$m_kv[$i][$j]=$val;
}
}


for ($i = 1; $i <= 6; $i++)
{
for ($j=1; $j <=4; $j++)
{
if(empty($m_kv[$i][$j])) $m_kv[$i][$j]=0;
}
}


return $m_kv;
}

//вызываю функцию
$k1=fun_kv(5);
$k2=fun_kv(10);
$k3=fun_kv(25);
$k4=fun_kv(40);


Вызываю я её несколько раз, для разных значений $dey, что приводит к торможению, один запуск функции даёт две сек, 4 раза уже - 8 сек.
Скажите пожалуйста, нельзя и дни как то в один запрос уложить?

Спустя 45 минут, 43 секунды (26.01.2011 - 09:34) sergeiss написал(а):
$dey - это и есть "день"? По-аглицки пишется day wink.gif

А вообще, у меня подозрение, что у тебя просто нету нормальных индексов.

Вот этот вопрос не понятен:
Цитата (zvezda_t @ 26.01.2011 - 09:49)
Скажите пожалуйста, нельзя и дни как то в один запрос уложить?


Спустя 2 минуты, 31 секунда (26.01.2011 - 09:37) kirik написал(а):
Цитата (zvezda_t @ 26.01.2011 - 00:49)
Скажите пожалуйста, нельзя и дни как то в один запрос уложить?

По логике запроса ты можешь взять максимальное значение $dey и получишь результат, который будет подходить для всех остальных значений (так как они меньше и запрос с наибольшим $dey захватит их записи тоже).

Цитата (sergeiss @ 26.01.2011 - 01:34)
$dey - это и есть "день"?

$ == зло
dey == дей
$+dey == злодей! smile.gif

Спустя 19 минут, 56 секунд (26.01.2011 - 09:57) zvezda_t написал(а):
sergeiss, знаю знаю... всё хочу по твоему совету добраться до индексов) мне давно пора всю БД как следует проиндексировать :)


Цитата
По логике запроса ты можешь взять максимальное значение $dey и получишь результат, который будет подходить для всех остальных значений (так как они меньше и запрос с наибольшим $dey захватит их записи тоже).
kirik, не совсем тебя поняла, для значения 40, конечно максимального запроса хватит, а вот для меньших значений и количество записей меньше же)

вот один из вариантов решения:

Select d.dey, vid, status, count(*) as kol_vo
from dbo.KVuser u
join (
select 5 as dey union all
select
10 as dey union all
select
25 as dey union all
select
40 as dey
) as d
on dey1 < d.dey or dey1 is null
where
status in (1, 2, 3, 4) and vid in(1,2,3,4,6)
Group by d.dey, vid, status


ps злодеи вы :) , смеётесь всё :rolleyes:

Спустя 9 минут, 12 секунд (26.01.2011 - 10:06) kirik написал(а):
zvezda_t
Подзапросы в случае с mysql - зло (да, зло.. а мы - добро smile.gif).

Цитата (zvezda_t @ 26.01.2011 - 01:57)
не совсем тебя поняла, для значения 40, конечно максимального запроса хватит

Да, меньше, но ведь они уже входят в те записи, которые ты выбрала, когда запросила 40, не так ли? И зачем их ещё раз доставать тогда?
Просто передавай в функцию массив дней, сортируй его по убыванию, бери первое значение из массива и составляй запрос только с ним.
Потом когда будешь разбирать результат запроса в цикле, просто записывай для каждого значения из массива дней результаты в его массив.

Спустя 2 минуты, 50 секунд (26.01.2011 - 10:09) zvezda_t написал(а):
kirik, ты взрываешь мой мозг... надо подумать...

зы. конечно добро smile.gif просто лапулечки! rolleyes.gif

Спустя 21 час, 20 минут, 52 секунды (27.01.2011 - 07:30) zvezda_t написал(а):
Цитата (kirik @ 26.01.2011 - 07:06)
Да, меньше, но ведь они уже входят в те записи, которые ты выбрала, когда запросила 40, не так ли? И зачем их ещё раз доставать тогда?
Просто передавай в функцию массив дней, сортируй его по убыванию, бери первое значение из массива и составляй запрос только с ним.
Потом когда будешь разбирать результат запроса в цикле, просто записывай для каждого значения из массива дней результаты в его массив.

kirik с последней фразой не разобралась:
Цитата
Потом когда будешь разбирать результат запроса в цикле, просто записывай для каждого значения из массива дней результаты в его массив.

так получается для каждого элемента массива дней мне отдельный запрос делать, чтоб для каждого получить свой результат? huh.gif

Спустя 16 часов, 1 минута, 24 секунды (27.01.2011 - 23:31) kirik написал(а):
Цитата (zvezda_t @ 26.01.2011 - 23:30)
так получается для каждого элемента массива дней мне отдельный запрос делать, чтоб для каждого получить свой результат?

Не.. зачем?)
В твоём случае начало будет звучать как-то так:

function fun_kv ($days)
{
rsort($days);
$day = $days[0];

$m_kv=array();

$result=mssql_query("Select dey1, vid, status, count(*) as kol_vo
from dbo.KVuser where
(dey1<"
. $day . " OR dey1 IS NULL)
and status in (1, 2, 3, 4) and vid in(1,2,3,4,6)
Group by vid, status"
);
while($row=mssql_fetch_array($result))
{
foreach($days as $day)
{
if($day < $row['dey1'])
{
break;
}
$m_kv[$day][$row['vid']][$row['status']]=$row['kol_vo'];
}
}

//....

в функцию передаешь массив с днями (array(50,10,30)), на выходе получается массив $m_kv вида:
array(
50 => array(
'vid' => array(
'status' => 'kol_vo',
// ...
),
// ...
),
30 => array(
'vid' => array(
'status' => 'kol_vo',
// ...
),
// ...
),
10 => array(
'vid' => array(
'status' => 'kol_vo',
// ...
),
// ...
)
)

тоесть 3 массива: для наших трёх дней из запроса (array(50,10,30)).

Спустя 8 часов, 16 минут, 22 секунды (28.01.2011 - 07:48) zvezda_t написал(а):
kirik, спасибо большое что наглядно показал :)

попробовала вызвать запрос:
1)
Select dey1, vid, status, count(*) as kol_vo
from dbo.KVuser where
(dey1<" . $day . " OR dey1 IS NULL)
and status in (1, 2, 3, 4) and vid in(1,2,3,4,6)
Group by vid, status


Вышла ошибка:

Цитата
Column 'dbo.KVuser.dey1' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.


если вывод делать без dey1, то работает:
2)
Select vid, status, count(*) as kol_vo
from dbo.KVuser where
(dey1<" . $day . " OR dey1 IS NULL)
and status in (1, 2, 3, 4) and vid in(1,2,3,4,6)
Group by vid, status


И еще вопрос:
Ведь в таблице dbo.KVuser, значение dey1 может принимать любые параметры (1, 2, 67 и тд).
Получается если для всех мы будем сумму считать, то потом как то суммы сложить надо ведь, для массива $m_kv[$day][$row['vid']][$row['status']] (ведь в него должно записаться количество строк где dey1<заданного значения. Например 5, значит туда войдут и суммы для 1 и для 2). Разве суммировать не нужно?(это я про твой вариант. В запросе 2)-я понимаю что выборка идет строго для одного ограничивающего параметра $day)


_____________

Что ты сделал сегодня - для завтра?
"Приидите ко Мне вси труждающиеся и обремененнии и Аз упокою вы, возмите иго Мое на себе и научитеся от Мене яко кроток есмь и смирен сердцем и обрящете покой душам вашим, иго бо Мое благо и бремя Мое легко есть."(Мф. 11:28-30)
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.