在mysql查询中强制计数为零

时间:2015-07-21 18:16:27

标签: php mysql

我有两个表t1, t2和以下查询:

SELECT t2.year,
       Count(t1.id) AS count
FROM   t1,
       t2
WHERE  t2.t1id = t1.id
       AND t2.year IN ( 1995, 1996, 1997, 1998,
                    1999, 2000 )
GROUP  BY t2.year
ORDER  BY t1.year 

结果是:

+----------+--------+
| year     | count  |
+----------+--------+
|     1995 |      1 |
|     1998 |      3 |
|     1999 |      3 |
|     2000 |     28 |
+----------+--------+

正如你所看到的那样,有些年头不见了。是否可以重写此查询以使其产生?

+----------+--------+
| year     | count  |
+----------+--------+
|     1995 |      1 |
|     1996 |      0 |
|     1997 |      0 |
|     1998 |      3 |
|     1999 |      3 |
|     2000 |     28 |
+----------+--------+

我可以使用php并检查缺少哪些行来填补缺失的空白,但这看起来效率不高..有什么想法吗?

修改

t1

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| name      | varchar(128) | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

t2

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| t1id      | int(11)      | NO   |     | NULL    |                |
| year      | int(11)      | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

例如:

t1

+----------+---------+
| id       | name    |
+----------+---------+
|        1 |    john |
|        2 |     bob |
|       .. |      .. |
+----------+---------+

t2

+----------+---------+---------+
| id       | t1id    |    year |
+----------+---------+---------+
|      100 |       1 |    1995 |
|      101 |       2 |    1998 |
|      103 |       3 |    1998 |
|       .. |      .. |      .. |  
+----------+---------+---------+

在结合之后,我最终得到:

+----------+---------+
| id       |    year |
+----------+---------+
|      100 |    1995 |
|      101 |    1998 |
|      103 |    1998 |
|       .. |      .. |  
+----------+---------+

4 个答案:

答案 0 :(得分:1)

SELECT t2.year,
       IF(Count(t1.id) > 0, Count(t1.id), 0)
FROM   t1,
       t2
WHERE  t2.t1id = t1.id
       AND t2.year IN ( 1995, 1996, 1997, 1998,
                    1999, 2000 )
GROUP  BY t2.year
ORDER  BY t1.year 

答案 1 :(得分:1)

如果没有您的查询可能涵盖的所有可能年份的来源,您将不得不使用php来执行此操作。一种方法可能看起来像这样。

function getCountsForRange(\PDO $dbConn, $startYear, $endYear){
    $ret = array_fill_keys(range($startYear, $endYear), 0);
    $stmt = $dbConn->prepare("SELECT t2.year,Count(t1.id) AS count ".
                             "FROM t1,t2 ".
                             "WHERE  t2.t1id = t1.id AND t2.year between ? and ? ".
                             "GROUP  BY t2.year ORDER  BY t1.year");

    $stmt->execute([$startYear, $endYear]);
    while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)){
        $ret[$row["year"]] = $row["count"];
    }
    return $ret;
}

答案 2 :(得分:0)

您需要以实际方式或在查询中自行处理空行,具体取决于具体情况。

见:

MySQL GROUP BY and Fill Empty Rows

Populating query results with empty rows

对于一些想法。

答案 3 :(得分:0)

create table yrCheat
(   year int not null
);

create table t1
(   -- forgive lack of PK
    id int not null,
    name varchar(128) not null
);

create table t2
(   -- forgive lack of PK
    id int not null,
    t1id int not null,
    year int not null
);

insert t1(id,name) values (100,'john'),(101,'bob'),(102,'sally');
insert t2(id,t1id,year) values (100,1,1995),(101,2,1998),(101,3,1998),(101,4,1998);
insert into yrCheat (year) values (1990),(1991),(1992),(1993),(1994),(1995),(1996),(1997),(1998),(1999),(2000);
-- etc

select yc.year,count(t1.id) as count
from yrCheat yc
left join t2
on t2.year=yc.year -- and yc.year in (1995,1996,1997,1998,1999,2000)
left join t1
on t1.id=t2.id
where yc.year in (1995,1996,1997,1998,1999,2000)
group by yc.year
order by yc.year

+------+-------+
| year | count |
+------+-------+
| 1995 |     1 |
| 1996 |     0 |
| 1997 |     0 |
| 1998 |     3 |
| 1999 |     0 |
| 2000 |     0 |
+------+-------+
6 rows in set (0.00 sec)