MySQL计数,左连接,分组返回零行

MySQL计数,左连接,分组返回零行,mysql,sql,count,group-by,Mysql,Sql,Count,Group By,在下面的sql语句中: SELECT `keywords`.keyID, count(`keywords-occurencies`.keyID) as countOccurencies FROM `keywords-occurencies` LEFT JOIN `keywords` ON `keywords-occurencies`.keyID = `keywords

在下面的sql语句中:

 SELECT `keywords`.keyID, count(`keywords-occurencies`.keyID) as countOccurencies 
                    FROM `keywords-occurencies`  
                    LEFT JOIN `keywords` 
                    ON `keywords-occurencies`.keyID = `keywords`.keyID 
                    WHERE `keywords-occurencies`.`keyID` IN (1,2,3) AND date BETWEEN '2013/01/25' AND '2013/01/27'
                    GROUP BY `keywords`.`keyID`
如果keyID 3没有返回值,则不会将其计为0,也不会包含在结果集中,并显示类似的结果

keyID countOccurencies
1       3
3       5
我想以如下方式显示零结果

keyID countOccurencies
1       3
2       0
3       5
要测试的样本数据:

--
-- Table structure for table `keywords`
--

CREATE TABLE IF NOT EXISTS `keywords` (
  `keyID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `keyName` varchar(40) NOT NULL,
  PRIMARY KEY (`keyID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `keywords`
--

INSERT INTO `keywords` (`keyID`, `keyName`) VALUES
(1, 'testKey1'),
(2, 'testKey2');

-- --------------------------------------------------------

--
-- Table structure for table `keywords-occurencies`
--

CREATE TABLE IF NOT EXISTS `keywords-occurencies` (
  `occurencyID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `keyID` int(10) unsigned NOT NULL,
  `date` date NOT NULL,
  PRIMARY KEY (`occurencyID`),
  KEY `keyID` (`keyID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `keywords-occurencies`
--

INSERT INTO `keywords-occurencies` (`occurencyID`, `keyID`, `date`) VALUES
(1, 1, '2013-01-27'),
(2, 1, '2013-01-26');

--
-- Constraints for table `keywords-occurencies`
--
ALTER TABLE `keywords-occurencies`
  ADD CONSTRAINT `keywords@002doccurencies_ibfk_1` FOREIGN KEY (`keyID`) REFERENCES `keywords` (`keyID`) ON DELETE CASCADE ON UPDATE CASCADE;

在日期上打勾:

SELECT 
`keywords`.keyID, 
count(`keywords-occurencies`.keyID) as countOccurencies 
FROM `keywords-occurencies`  
LEFT JOIN `keywords`  ON `keywords-occurencies`.keyID = `keywords`.keyID 
WHERE `keywords-occurencies`.`keyID` IN (1,2,3) AND `date` BETWEEN '2013/01/25' AND '2013/01/27'
GROUP BY `keywords-occurencies`.`keyID`

要做的事情

  • 您应该使用
    按关键字分组。keyID
  • 而且您必须显示的是
    关键字发生率.keyID
    而不是
    关键字.keyID
  • 计数
    关键字.keyID
  • (可选)使用
    别名
    ,这样您就可以消除表名以外的反勾号
质疑,

SELECT  a.keyID,
        count(b.keyID) AS countOccurencies
FROM    `keywords - occurencies` a
        LEFT JOIN `keywords` b
            ON a.keyID = b.keyID
WHERE   a.keyID IN ( 1, 2, 3 ) AND 
        DATE BETWEEN '2013/01/25' AND '2013/01/27'
GROUP   BY a.keyID
SELECT  a.keyID,
        count(b.keyID) AS countOccurencies
FROM    `keywords` a
        LEFT JOIN `keywords-occurencies` b
            ON a.keyID = b.keyID AND
               b.DATE BETWEEN '2013-01-25' AND '2013-01-27'
WHERE   a.keyID IN ( 1, 2, 3 ) 
GROUP   BY a.keyID

更新1

根据示例记录,您需要执行以下操作:

  • 交换桌名
  • 将此条件
    日期介于'2013-01-25'和'2013-01-27'之间
    放在连接条款的
  • (可选)使用
    别名
    ,这样您就可以消除表名以外的反勾号
质疑,

SELECT  a.keyID,
        count(b.keyID) AS countOccurencies
FROM    `keywords - occurencies` a
        LEFT JOIN `keywords` b
            ON a.keyID = b.keyID
WHERE   a.keyID IN ( 1, 2, 3 ) AND 
        DATE BETWEEN '2013/01/25' AND '2013/01/27'
GROUP   BY a.keyID
SELECT  a.keyID,
        count(b.keyID) AS countOccurencies
FROM    `keywords` a
        LEFT JOIN `keywords-occurencies` b
            ON a.keyID = b.keyID AND
               b.DATE BETWEEN '2013-01-25' AND '2013-01-27'
WHERE   a.keyID IN ( 1, 2, 3 ) 
GROUP   BY a.keyID

  • 有两件事。您需要根据左侧外部联接的第一部分上的id进行分组。然后你需要数一数第二面是什么。对于右外部联接,顺序相反:

    SELECT k.keyID, count(ko.keyID) as countOccurencies 
    FROM `keywords-occurencies` ko
          RIGHT JOIN `keywords` k
          ON ko.keyID = k.keyID 
    WHERE k.`keyID` IN (1,2,3) AND date BETWEEN '2013/01/25' AND '2013/01/27'
    GROUP BY k.`keyID`
    
    其原因与左侧外部联接有关。它将所有内容保留在第一个表中,即使没有匹配项。所以,这就是你得到完整列表的地方。至于计数,您要对匹配项进行计数。如果在第一个表中计算id,则始终会得到至少1。计算第二个表中的id可以得到0


    请注意,我还向您的表中添加了别名,以使查询更具可读性。

    将其更改为
    左连接对我来说很有效:

    SELECT k.keyID, count(ko.keyID) as countOccurencies 
    FROM `keywords-occurencies` ko
          LEFT JOIN `keywords` k
          ON ko.keyID = k.keyID 
    WHERE k.`keyID` IN (1,2,3) AND date BETWEEN '2013/01/25' AND '2013/01/27'
    GROUP BY k.`keyID`
    

    谢谢您的更正,但是上面的查询仍然没有返回0结果行。您能提供我们可以使用的示例记录吗?当然,我将它们添加到了我的问题中。我认为您需要交换这些表名,并在加入它们时将的条件放在,而不是放在
    WHERE
    子句上。将所有左连接的列依赖项移动到左连接子句(而不是in和子句)中,对我来说也非常有效。非常感谢。谢谢,但查询仍然不会返回0结果行。@SportBilly。根据表的名称,我认为您需要一个正确的外部联接——我猜关键字表包含所有关键字,并且出现的值可能为0。我相应地修改了查询。@SashiKant关于刚才的问题。。。真的评论没有意义;)欢迎来到StackOverflow。要在文章中插入代码,请使用“代码示例”按钮,而不是“代码片段”按钮。snippet按钮仅适用于HTML/CSS/JS