MySQL计数,左连接,group by返回零行

时间:2013-01-27 15:55:52

标签: 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`.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;

4 个答案:

答案 0 :(得分:6)

<击>

<击>

要做的事情

  • 您应该使用GROUP BY keywords-occurencies.keyID
  • 对其进行分组
  • ,您必须显示keywords-occurencies.keyID而不是keywords.keyID
  • COUNT keywords.keyID
  • 可选)使用ALIAS,这样您就可以摆脱tableNames以外的反引号

查询,

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

<击>

更新1

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

  • 交换tableNames
  • 将此条件DATE BETWEEN '2013-01-25' AND '2013-01-27'置于加入的ON条款中。
  • 可选)使用ALIAS,这样您就可以摆脱tableNames以外的反引号

查询,

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 :(得分:2)

date ::

上打勾
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`

答案 2 :(得分:1)

有两件事。您需要按左外连接的 first 部分的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。

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

答案 3 :(得分:0)

将其更改为 @Override public boolean dispatchKeyEvent(KeyEvent event) { int action = event.getAction(); int keyCode = event.getKeyCode(); switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: if (action == KeyEvent.ACTION_DOWN) { //TODO } return true; case KeyEvent.KEYCODE_VOLUME_DOWN: if (action == KeyEvent.ACTION_DOWN) { //TODO } return true; default: return super.dispatchKeyEvent(event); } } 对我有用:

LEFT JOIN