从两个表中获取单词数

时间:2017-01-23 16:33:05

标签: mysql sql

我有两个表:z_wordsz_words_products。您可以看到这些表格的结构。

z_words_products表中可以是相同的值:

wordIdsmaIdproductIdsiteIdtype值不同。

我想得到什么,得到1个数字,一个计数。我想知道,我的表中有多少单词,但是一个单词在一个产品中就算一个,即使它在一个产品中出现两次。

例如:

SELECT `zw`.`word`, `zwp`.`smaId`, COUNT(*) AS `cnt` 
FROM `z_words` `zw`
INNER JOIN `z_words_products` `zwp` ON `zwp`.`wordId` = `zw`.`id`
WHERE `zwp`.`siteId` = 0 
AND `zwp`.`smaId` = 1 
GROUP BY `zw`.`word`, `zwp`.`smaId`  

输出

+--------------+-------+-----+
|     word     | smaId | cnt |
+--------------+-------+-----+
| 8100         |     1 |   1 |
| 8102wlci     |     1 |   1 |
| 8104wlmi     |     1 |   1 |
| Acer         |     1 |   2 |
| unknown      |     1 |   1 |
+--------------+-------+-----+

如您所见,Acer发现了twince,因为它处于类型A并且类型为B,但我在最终结果中应该计为1。

所以我的最终查询结果应该是5,而不是6.当然,我的表中有很多产品。

我试过这个:

SELECT COUNT(cnt) FROM (
   SELECT `zw`.`id` AS `cnt` 
   FROM `z_words` `zw`
   INNER JOIN `z_words_products` `zwp` ON `zwp`.`wordId` = `zw`.`id`
   WHERE `zwp`.`siteId` = 0 
   AND `zwp`.`smaId` = 1
   GROUP BY `zw`.`word`, `zwp`.`smaId`) 
 AS xxx

它有效,给了我正确的结果。我的问题是,当我在所有产品上运行时,它需要6-7分钟。

还有其他方法可以让结果更快吗?

z_words_products是6 147 059条记录中,z_words表中有367 771

查询的Eplain:

+----+-------------+------------+--------+-----------------------------------------------+--------------+---------+------------------------+------+----------------------------------------------+
| id | select_type |   table    |  type  |                 possible_keys                 |     key      | key_len |          ref           | rows |                    Extra                     |
+----+-------------+------------+--------+-----------------------------------------------+--------------+---------+------------------------+------+----------------------------------------------+
|  1 | PRIMARY     | <derived2> | ALL    | \N                                            | \N           | \N      | \N                     |   14 |                                              |
|  2 | DERIVED     | zwp        | ref    | PRIMARY,siteId_smaId,wordId,wordId_2,wordId_3 | siteId_smaId | 8       | const,const            |   14 | Using index; Using temporary; Using filesort |
|  2 | DERIVED     | zw         | eq_ref | PRIMARY                                       | PRIMARY      | 4       | partcollect.zwp.wordId |    1 |                                              |
+----+-------------+------------+--------+-----------------------------------------------+--------------+---------+------------------------+------+----------------------------------------------+

表格

CREATE TABLE `z_words` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `word` varchar(255) DEFAULT NULL,
  `translated` varchar(255) DEFAULT NULL,
  `transTry` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `word` (`word`)
) ENGINE=InnoDB AUTO_INCREMENT=526303 DEFAULT CHARSET=utf8

CREATE TABLE `z_words_products` (
  `wordId` int(11) NOT NULL,
  `smaId` int(11) NOT NULL,
  `productId` int(11) NOT NULL,
  `type` enum('word','compatible','partNumber','tag','model') NOT NULL,
  `siteId` int(11) NOT NULL DEFAULT '0',
  `order` int(11) DEFAULT NULL,
  PRIMARY KEY (`wordId`,`smaId`,`productId`,`type`,`siteId`),
  KEY `siteId_smaId` (`siteId`,`smaId`),
  KEY `wordId` (`wordId`,`productId`),
  KEY `wordId_2` (`wordId`,`order`),
  KEY `wordId_3` (`wordId`),
  KEY `wordId_4` (`productId`,`order`),
  CONSTRAINT `z_words_products_ibfk_1` FOREIGN KEY (`wordId`) REFERENCES `z_words` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 个答案:

答案 0 :(得分:0)

您应该可以使用SELECT COUNT(DISTINCT...)表格上的z_words_products在相应的列上编写查询,省略type列。

很难确切地告诉您如何定义计数,但根据您的两个示例查询,您希望为给定的wordId对计算(sitId,smaId)的不同值。

如果这个假设是正确的,那么这个查询应该适合你:

SELECT count(distinct `zwp`.`wordId`)
FROM `z_words_products` `zwp`
WHERE `zwp`.`siteId` = 0 
AND `zwp`.`smaId` = 1;