避免查询的null结果

时间:2013-09-23 14:25:53

标签: php mysql

假设这个

用户表: [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

6 个答案:

答案 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语句解决

  1. 首先选择所有发生

  2. 第二次选择每次发生的所有选票并合并值

  3. 这是我的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 );
        }
    }