SQL Join和Count返回意外匹配

时间:2016-07-26 05:43:28

标签: mysql sql

TBL1

 type|price
 ----------
 1   | 10
 2   | 15

TBL2

 type|expires
 ----------
 1   | 2015-01-01
 1   | 2017-01-01
 1   | 2017-01-01
 2   | 2015-01-01
 2   | 2017-01-01

我想查询一个查询,该查询返回tbl1中给定类型的数据,以及tbl2中该类型的当前(未过期)记录的数量。这是我的疑问:

select tbl1.*,
count(if(tbl2.expires > now(),1,null)) current
from tbl1 left join tbl2
on tbl1.type=tbl2.type
where tbl1.type = 1

正如所料,它返回:

type|price|current
1   | 10  | 2

然而,当我要求一个不存在的类型时,我期望0结果。但是,如果我将查询中的类型替换为3,我会得到:

type|price|current
NULL|NULL | 0

请帮助我理解

  1. 该记录如何与查询匹配? (我期望一个空的结果集)
  2. 如何获得我期望的行为? (即没有结果不存在type
  3. Live demo

6 个答案:

答案 0 :(得分:2)

我会试试这个:

select type , count(counter) from (
select tbl1.type type,tbl2.expires counter
  from tbl1 left join tbl2
    on tbl1.type=tbl2.type
 where tbl1.type = 1
   and tbl2.expires > now()
) t
 group by type   ;

不同之处在于,在您的查询中,如果没有匹配的数据(if(tbl2.expires > now(),1,null)),您仍然会返回一些内容。

答案 1 :(得分:1)

使用像from django.db import models from trunk.profiles.models import Profiles # source of error class ContentObject(models.Model): course_name = models.CharField(max_length15) course_topic = models.CharField(max_length = 30) op_UserName = models.ForeignKey(Profiles) 这样没有count子句的聚合函数会返回总是一行。

解决方法是将查询包装在子查询中,并在外部查询中再次检查group by

type

Demo here

答案 2 :(得分:1)

您应该注意,所有聚合查询将至少返回单行作为结果

看看这个例子

SELECT 1
where 1=0;

以上返回空结果。但是以下

SELECT SUM(1)
where 1=0;

将NULL作为单行返回

答案 3 :(得分:1)

尝试此查询:

SELECT 
    tbl1.type
    ,tbl1.price
    ,count(A.expires) 
FROM tbl1 
INNER JOIN 
(
    SELECT 
         tbl2.type
         ,tbl2.expires
    FROM tbl2
    WHERE tbl2.expires > now()
) AS A
ON tbl1.type = A.type
WHERE tbl1.type = 3
GROUP BY tbl1.type

修改

仅供参考:虽然上述查询有效但与SQL Server或其他SQL产品不兼容,但无法在那里运行。

以下查询适用于任何支持内部联接和日期函数的SQL产品,以获取当前日期。只需对目标sql产品中的类似函数替换Now()进行更改。

MySql在某些方面似乎很有用。

SELECT 
    tbl1.Type
    ,tbl1.Price
    ,A.ExpCount
FROM tbl1 
INNER JOIN 
(
    SELECT 
        tbl2.Type
        ,COUNT(tbl2.Expires) ExpCount
    FROM tbl2
    WHERE tbl2.expires > NOW()
    GROUP BY tbl2.Type
) AS A
ON tbl1.type = A.type
WHERE tbl1.type = 1

答案 4 :(得分:0)

感谢您的回复。在首先从Giorgos学习到聚合函数而没有group by 总是返回一些东西时,我只是添加了一个group by子句。这是我选择的查询:

select tbl1.*, count(*) current
from tbl1 left join tbl2
on tbl1.type=tbl2.type
where tbl1.type=3 and tbl2.expires > now()
group by tbl1.type

谢谢大家。

答案 5 :(得分:0)

SELECT T.* , (SELECT COUNT(*) FROM TBL2 WHERE TYPE = T.TYPE AND EXPIRES >= SYSDATE )  current
 FROM TBL1 T
WHERE T.TYPE = 1 ;

/* IF TBL2.EXPIRES DATA TYPE IS NOT DATE AT FIRST YOU SHOULD MAKE IT DATE *\