2015-09-24 3 views
0

Я пытаюсь подсчитать объявления для разных диапазонов цен, но мой запрос не выводится, когда count равен нулю, и поэтому я не могу связать это с массивом диапазонов.SELECT CASE с COUNT нет вывода, когда COUNT = 0

Как это:

Это массив цена пробьет:

$arr_pri = array(1, 30000, 50000, 75000, 100000, 125000, 150000, 175000, 200000, 300000, 400000); 

Это вот вопрос:

$ctpri = count ($arr_pri); 

$ctmod_pri = array(); 

$arr_i=$arr_k=''; 

$sql = "SELECT `range`, COUNT(`ad_id`) as ctads FROM (
     SELECT CASE "; 
     for ($i=0; $i < $ctpri-1; $i++){ 
      $k=$i+1; 
      $arr_i=$arr_pri[$i]+1; 
      $arr_k=$arr_pri[$k]; 

$sql .= "WHEN price BETWEEN {$arr_i} AND {$arr_k} THEN CAST('{$i}' AS UNSIGNED) ";} 

$sql .= " END AS `range`, ad_id FROM ads 
WHERE published = 'Y' 
AND deleted = 'N') AS t GROUP BY `range`"; 
$stmt = $ulink->prepare($sql); 
$stmt->execute(); 
while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) { 
    ctmod_pri[] = $r['ctads']; 
} 

Типичный выход для $ ctmod_pri является:

array(5) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "1" [3]=> string(1) "1" [4]=> string(1) "1" } 

Я ожидал, что он создаст массив из 10 элементов, по одному для каждого ценового диапазона (0-30000, 30001-50000 ....), также выводя нулевые результаты.

Что мне не хватает?

+0

Выражение 'CASE' никогда не будет генерировать недостающие значения, если не соответствует ни одной строки, так что нет ничего«подсчитывать 0 из «. Но вы возвращаете столбец под названием «диапазон», а затем выбрасываете его. Почему бы вам не использовать его для сопоставления, вместо того чтобы пытаться использовать ярлык и просто получить массив значений ctads? Также обратите внимание, что вы всегда должны добавлять 'ORDER BY', если вы ожидаете определенного заказа. 'GROUP BY' иногда сортируется, но вы не должны зависеть от неявного, но технически неопределенного порядка. –

ответ

1

Как отметил Майкл-sqlbot, CASE не будет делать то, что вы хотите. Я не совсем уверен в желаемом выходе, но попробую этот запрос.

SELECT '2-30000' AS `range`, SUM(CASE WHEN price BETWEEN 2 AND 30000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '30001-50000' AS `range`, SUM(CASE WHEN price BETWEEN 30001 AND 50000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '50001-75000' AS `range`, SUM(CASE WHEN price BETWEEN 50001 AND 75000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '75001-100000' AS `range`, SUM(CASE WHEN price BETWEEN 75001 AND 100000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '100001-125000' AS `range`, SUM(CASE WHEN price BETWEEN 100001 AND 125000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '125001-150000' AS `range`, SUM(CASE WHEN price BETWEEN 125001 AND 150000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '150001-175000' AS `range`, SUM(CASE WHEN price BETWEEN 150001 AND 175000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '175001-200000' AS `range`, SUM(CASE WHEN price BETWEEN 175001 AND 200000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '200001-300000' AS `range`, SUM(CASE WHEN price BETWEEN 200001 AND 300000 THEN 1 ELSE 0 END) AS `ctads` FROM ads 
union 
SELECT '300001-400000' AS `range`, SUM(CASE WHEN price BETWEEN 300001 AND 400000 THEN 1 ELSE 0 END) AS `ctads` FROM ads; 

Будет подсчитано количество объявлений в указанном диапазоне цен. Вы можете изменить 2-30000 на 0 и так далее, если это то, что вам нужно.

THEN 1 else 0 в основном означает, что если строка удовлетворяет КОГДА часть, она говорит, добавить 1 в противном случае добавьте 0.

+0

Спасибо @ Давид Фэрбенкс. Я принимаю это как решение, но я несколько разочарован тем, насколько он доволен. Хуже того, это очень трудоемко. Я рассматриваю возможность просто не размещать эту информацию в своем приложении, все они учитываются. – BernardA

Смежные вопросы