简体   繁体   English

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

[英]MySQL count, left join, group by to return zero rows

In the below sql statement: 在下面的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`

If keyID 3 has no return values it is not counted as 0 and it is not included in the result set and a result like this is displayed 如果keyID 3没有返回值,则不计为0并且它不包含在结果集中,并显示如下结果

keyID countOccurencies
1       3
3       5

I would like to display the zero results like 我想显示零结果

keyID countOccurencies
1       3
2       0
3       5

Sample data to test with: 要测试的样本数据:

--
-- 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;

things to do 要做的事情

  • you should be grouping it with GROUP BY keywords-occurencies.keyID 你应该用 GROUP BY keywords-occurencies.keyID对它进行分组
  • and you must be displaying keywords-occurencies.keyID not the keywords.keyID 你必须显示 keywords-occurencies.keyID而不是 keywords.keyID
  • COUNT keywords.keyID COUNT个 keywords.keyID
  • ( optional ) use ALIAS so you can get rid of the backticks other than tableNames 可选 )使用 ALIAS这样你就可以摆脱tableNames以外的反引号

query, 查询,

 
 
 
  
  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
 
  

UPDATE 1 更新1

Based on the example records, you need to do the following, 根据示例记录,您需要执行以下操作,

  • interchange the tableNames 交换tableNames
  • put this condition DATE BETWEEN '2013-01-25' AND '2013-01-27' on the ON clause of join. 将此条件设置为DATE BETWEEN '2013-01-25' AND '2013-01-27'的加入ON条款。
  • ( optional ) use ALIAS so you can get rid of the backticks other than tableNames 可选 )使用ALIAS这样你就可以摆脱tableNames以外的反引号

query, 查询,

 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 

Put a back tick on date :: 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`

There are two things. 有两件事。 You need to group by the id on the first part of the left outer join. 您需要按左外连接的第一部分上的id进行分组。 You then need to count what is one the second side. 然后你需要计算第二方是什么。 For a right outer join, the order is the opposite: 对于右外连接,顺序相反:

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`

The reason for this has to do with the left outer join. 其原因与左外连接有关。 It keeps everything in the first table, even when there are no matches. 它将所有内容保存在第一个表中,即使没有匹配项也是如此。 So, that is where you get the complete list. 所以,这就是你获得完整列表的地方。 As for the count, you want to count matches. 至于计数,你想要计算匹配。 If you count the id in the first table, you will always get at least 1. Counting the id in the second table allows you to get 0. 如果计算第一个表中的id,则总是至少得到1.在第二个表中计算id可以得到0。

Notice I also added aliases to your table to make the query more readable. 注意我还在表中添加了别名,以使查询更具可读性。

Changing that to LEFT JOIN worked for me: 将其更改为LEFT JOIN对我LEFT JOIN

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`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM