MySQL. Выборка из базы. COUNT по двум полям.

Krisha

pain in the neck
MySQL. Выборка из базы. COUNT по двум полям.

Есть в таблице есть 2 поля Failed и Passed, необходимо сделать выборку, могу сделать это 2'мя запросами:
[sql]
SELECT COUNT(Failed) AS Failed FROM Statistics WHERE DriverID = '".$id."' AND Failed != '0';

SELECT COUNT(Passed) AS Passed FROM Statistics WHERE DriverID = '".$id."' AND Passed = '1';
[/sql]

Можно ли как-то сделать это одним запросом ?

P.S. Нужно для MySQL 3.23.54
 

Popoff

popoff.donetsk.ua
Re: MySQL. Выборка из базы. COUNT по двум полям.

[тьфу, спал мало, глупости написал :)]
 

Sleeper

Guest
Попробуй так:

select COUNT( Failed ) AS Failed, COUNT( Passed ) AS Passed from
Statistics where DriverID = '".$id."' group by DriverID having Failed != '0' and Passed = '1';
 

Popoff

popoff.donetsk.ua
Автор оригинала: Sleeper
Попробуй так:

select COUNT( Failed ) AS Failed, COUNT( Passed ) AS Passed from
Statistics where DriverID = '".$id."' group by DriverID having Failed != '0' and Passed = '1';
Еще один :)

Не будет ли это аналогично запросу
[sql]select COUNT(1) AS Failed, COUNT(1) AS Passed from
Statistics where DriverID = '".$id."' and Failed != '0' and Passed = '1';[/sql]
?

Хорошо бы уточнить, какие данные хранятся в этих таблицах. Если там только нолики и единички, то можно использовать sum. Все зависит от того, есть ли в этих столбцах пустые значения (NULL) и значения, отличные от 0 и 1 :)
 

Sleeper

Guest
Мне вообще интересно для чего задается условие на count()...
И как оно отрабатывает...
Ладно сейчас попробую
 

Krisha

pain in the neck
Popoff
там числа, Failed - от 0 и более, Passed 0 или 1, SUM увы не покатит.

-~{}~ 25.02.04 19:24:

Sleeper
Нужно постичать кол-во записей, у которых Failed != 0 и кол-во записей, у кот. Passed = 1, на выходе получить: Failed = столько, Passed = столько.
 

Sleeper

Guest
Получилось что-то в этом духе, и вроде работает нормально
SELECT count(IF (Passed =1, passed, NULL ) ) AS Passed,
count(IF (Failed !=0, Failed, NULL)) AS Failed
FROM Statistics
WHERE DriverID =1
 

Popoff

popoff.donetsk.ua
SELECT sum(Passed =1) AS Passed,
sum(Failed !=0) AS Failed
FROM Statistics
WHERE DriverID =1
 

Falc

Новичок
Popoff,Sleeper
Для ускорения нужно добавить условие:
WHERE DriverID = '".$id."' AND ( Failed != '0' OR Passed = '1' );


Krisha
Если записей очень много, то при наличии совтавных индексов в 2 запроса будет работать быстрее.
 

Sleeper

Guest
2Falc
Угу.

Popoff
sum(Failed !=0) не даст правильное количество если failed будет не только 0 и 1, но и что-нить другое.
 

Falc

Новичок
Sleeper
>>sum(Failed !=0) не даст правильное количество если failed будет не только 0 и 1, но и что-нить другое.
Почему?
 

Popoff

popoff.donetsk.ua
Для ускорения нужно добавить условие:
WHERE DriverID = '".$id."' AND ( Failed != '0' OR Passed = '1' );
будет ли от этого быстрее?
MySQL normally uses the index that finds the least number of rows. An index is used for columns that you compare with the following operators: =, >, >=, <, <=, BETWEEN, and a LIKE with a non-wild-card prefix like 'something%'.
Это означает, что для
PHP:
Failed != '0'
индексы использоваться не будут никогда.
... WHERE index=1 OR A=10 /* Index is not used in both AND parts */
Это означает, что и для всего выражения в скобках индекс использоваться не будет.

Если эту дополнительную проверку не добавить, то он просто добавит 0 или 1 в зависимости от истинности условия внутри sum или count. Если добавить, то он сначала проверит, а потом равно прибавит (и сравнит еще раз внутри сложения).

Если записей очень много, то при наличии совтавных индексов в 2 запроса будет работать быстрее.
Для второго случая все равно все строки с DriverID = '".$id."' перебирать придется. Поэтому не будет.

-~{}~ 26.02.04 10:34:

Тьфу, для первого :)
Для того, в котором есть сравнение на неравенство :)
 

Sleeper

Guest
Popoff
Failed - от 0 и более
Чему будет равен sum если failed у нас будет 0,0,1,1,2,2,3,3,4,4,5,5 ?

По поводу скорости - точно не знаю, поэтому говорить не буду.
 

Falc

Новичок
Popoff
>>Если эту дополнительную проверку не добавить, то он просто добавит 0 или 1 в зависимости от истинности условия внутри sum или count. Если добавить, то он сначала проверит, а потом равно прибавит (и сравнит еще раз внутри сложения).

Сейчас проверил вот такой запрос:
SELECT SUM(field !=0)
FROM table
WHERE field !=0

На таблице с 90% записей с field = 0
Скорость оказалась равной. Это логично, т.к. в одном случае делается лишнее сравнение, а в другом лишнее сложение. Подозреваю что и в приведеном примере скорости будут примерно одинаковые.

>>Это означает, что и для всего выражения в скобках индекс использоваться не будет.
>>Для второго случая все равно все строки с DriverID = '".$id."' перебирать придется. Поэтому не будет.

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

Popoff

popoff.donetsk.ua
Sleeper
Чему будет равен sum если failed у нас будет 0,0,1,1,2,2,3,3,4,4,5,5 ?
Согласен, в таком случае можно было бы заменить Failed!=0 на Failed>0. При такой операции мускл может использовать индексы.

Falc
Но справедливости ради замечу что они также могут и замедлить выборку.
Когда? :)
 

Krisha

pain in the neck
В общем получился вот такой запрос как я понял:
PHP:
SELECT count(IF (Passed = 1, Passed, NULL ) ) AS Passed, count(IF (Failed != 0, Failed, NULL)) AS Failed
FROM Statistics
WHERE DriverID = '$id' AND ( Failed != '0' OR Passed = '1' )
Вроде работает, спасибо.
 

Falc

Новичок
Krisha
Что через сумму не работает?


Popoff
>>Когда?
Чесно говоря я не совсем понял почему, но когда тестил запрос:
SELECT SUM(field !=0)
FROM table
WHERE field !=0

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

Krisha

pain in the neck
Falc
Sum посчитает мне сумму значений в поле Failed, а так как это поле не 0\1, а может быть 0 и 1, 2.... и т.д. то я получу неверный результат.
 
Сверху