2013-09-23 4 views
0

предположим, этотИзбегайте нулевые результаты запроса

пользователя таблицу: [ID] [почта] [пропуск]

случаться таблица: [ID] [UID] [дата] [содержание]

стол голос [UID] [сокрытая] [тип] [DateTime]

1 пользователь может иметь 0 или более случиться, 1 случиться может иметь 0 или больше голосов ..

Я хочу, чтобы получить общее количество голосов для конкретного случаться

SELECT 
H.*, 
SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END) AS upvotes, 
SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END) AS downvotes 
FROM 
happens H 
LEFT JOIN 
votes AS V 
ON V.hid = H.id 
WHERE 
H.uid = :uid 

проблема заключается в том, что если нет голосов не связано на случаться я получаю пустую строку из MySQL, не EMPTY, но NULL

как могу ли я избежать этого нулевого результата?

[править]

некоторые попытки:

основной

SELECT H.* FROM happens H LEFT JOIN votes AS V ON V.hid = H.id WHERE H.uid = '178d937' 

результат -> пустой

Все остальные пытаются с SUM, COUNT, HAVING ЭСТ ЭСТ дает:

[id] [uid] [what] [latitude] [longitude] [date] [time] [hide] [upvotes] [downvotes] 
NULL NULL NULL NULL NULL NULL NULL NULL 0 0 
+1

попробуйте это, вместо использования 'SUM' используйте' COUNT'. например, 'COUNT (CASE WHEN V.type = 'C' THEN 1 ELSE NULL END)' –

+0

id uid, какая долгота даты по дате скрыть верхние горизонты downvotes NULL NULL NULL NULL NULL NULL NULL NULL 0 0 – Mindexperiment

ответ

1

Использования HAVING для проверки нулевой

SELECT 
H.*, 
SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END) AS upvotes, 
SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END) AS downvotes 
FROM 
happens H 
LEFT JOIN 
votes AS V 
ON V.hid = H.id 
WHERE 
H.uid = :uid 
HAVING upvotes IS NOT NULL 
+0

это решение с использованием HAVING H. id IS NOT NULL works .. – Mindexperiment

+0

Прошу прощения, теперь у пользователей с некоторыми случаями, а некоторые голоса я получаю только 1 строку, даже если есть 4/5 строк для отображения ..... – Mindexperiment

+0

Я предоставил наличие у вас «НАВИГАЮЩИЕ» upvotes IS NOT NULL' не на 'H.id' и вы можете поделиться с нами sqlfiddle с некоторыми примерами данных –

1
SELECT H.*, 
    SUM(IFNULL(V.type = 'C', 0)) AS upvotes, 
    SUM(IFNULL(V.type = 'R', 0)) AS downvotes 
+0

нулевые значения находятся в результирующем наборе не в таблице голосования ... запрос возвращает нулевые поля – Mindexperiment

1

Если вы измените ваш LEFT JOIN к INNER JOIN (или просто JOIN), вы только получите происходит запись, которые имеют, по меньшей мере, 1, связанную запись в голосах таблица:

SELECT 
H.*, 
SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END) AS upvotes, 
SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END) AS downvotes 
FROM 
happens H 
INNER JOIN 
votes AS V 
ON V.hid = H.id 
WHERE 
H.uid = :uid 

Заканчивать http://www.w3schools.com/sql/sql_join.asp для получения информации о различных типах присоединиться.

EDIT:

Итак, чтобы получить все это происходит, но с 0 для тех, кто без голосов попробовать (добавить COALESCE):

SELECT 
H.*, 
COALESCE(SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END),0) AS upvotes, 
COALESCE(SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END),0) AS downvotes 
FROM 
happens H 
LEFT JOIN 
votes AS V 
ON V.hid = H.id 
WHERE 
H.uid = :uid 
+0

Мне нужно все, что происходит с голосами или без них :) – Mindexperiment

+0

просто попробуйте, но тот же результат ... может быть, проблема в H . * ??? потому что я пытаюсь получить результат от пользователя, который не был добавлен ... – Mindexperiment

+0

Вы должны получить пустой результат для пользователя, который ничего не имеет в вашей таблице событий с указанным выше. Можно вернуть строку для пользователя, даже если в ней нет записей, с подсчетом 0 для голосов, но не будет данных о том, чтобы связать их (все поля события будут NULL), поэтому Я не уверен, что вы пытаетесь сделать. –

0
SELECT 
H.*, 
COALESCE(SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END), 0) AS upvotes, 
COALESCE(SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END), 0) AS downvotes 
0

Соединение слева возвращает все строки на слева и NULL значения справа, если условие ON не соответствует. Используйте внутреннее соединение.

+0

уже попробовать с INNER JOIN, но всегда тот же результат ... строка со значениями NULL – Mindexperiment

+0

@Mindexperiment Можете ли вы опубликовать образец результата ? – Mihai

0

решается с помощью 2 о

  1. сначала выбрать все произойдет

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

вот решение с моей PHP happenModel класс:

public function getUserHappensWithVotes() { 
$selectQuery = <<<QUERY 
SELECT 
SUM(CASE WHEN V.type='C' THEN 1 ELSE 0 END) AS upvotes, 
SUM(CASE WHEN V.type='R' THEN 1 ELSE 0 END) AS downvotes 
FROM 
votes V 
WHERE 
V.uid = :uid 
AND 
V.hid = :hid 
QUERY; 

    // get all happen as array of class 
    $userHappens = $this->userHappens; 
    // empty container 
    $happenWithVotes = array(); 

    foreach($userHappens AS $happen) { 
     $sql = $this->pdo->prepare($selectQuery); 
     $sql->execute(array(':uid'=>$happen->uid, ':hid'=>$happen->id)); 

     // fetching the count of up and down votes of every happen 
     $votes = $sql->fetch(PDO::FETCH_ASSOC); 
     // merging happen class as array with votes 
     $happen = array_merge((array) $happen, $votes); 

     // rebuild the userHappen array 
     $happenWithVotes[] = (object) $happen; 
    } 

    if ($this->encoder) { 
     return $this->encoder->setData($this->parse($happenWithVotes))->encode(); 
     } else { 
     return $this->parse($happenWithVotes); 
    } 
} 
Смежные вопросы