假设这个
用户表: [id] [mail] [pass]
发生表: [id] [uid] [日期] [内容] 投票表 [uid] [hid] [type] [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
答案 0 :(得分: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
答案 1 :(得分:1)
SELECT H.*,
SUM(IFNULL(V.type = 'C', 0)) AS upvotes,
SUM(IFNULL(V.type = 'R', 0)) AS downvotes
答案 2 :(得分: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以获取有关不同联接类型的信息。
修改强>
好的,所以要把所有事情都发生,但对于那些没有投票的人来说是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
答案 3 :(得分: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
答案 4 :(得分:0)
如果ON条件不匹配,则Left Join将返回左侧的所有行和右侧的NULL值。使用Inner Join。
答案 5 :(得分:0)
使用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 );
}
}