我有一张桌子,
| PAGELETS | CREATE TABLE `PAGELETS` (
`page_key` int(32) unsigned NOT NULL,
`pagelet_serial` int(32) unsigned NOT NULL,
`pagelet_shingle` int(32) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
我想:
1) Find all the pagelet_shingles where quantity > 1 ( occurs more than once)
2) out of these only output those that have different page_key
这是产生半正确答案的查询:
SELECT * FROM PAGELETS WHERE pagelet_shingle IN( SELECT pagelet_shingle FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(DISTINCT page_key) > 1) ORDER BY pagelet_shingle;
不幸的是,在一个小数据集上大约需要18秒;
我有另一个查询,
SELECT dt1.* FROM
(SELECT * FROM PAGELETS
GROUP BY page_key, pagelet_shingle HAVING COUNT(*) = 1)
dt1 JOIN
(SELECT * FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(*) > 1)
dt2 USING (pagelet_shingle) ORDER BY pagelet_shingle
由技术上不正确的专家给出(与你有关的事情不能SELECT * .. GROUP)但是会产生更快的结果,其中
SELECT * FROM PAGELETS WHERE pagelet_shingle = 57
+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
| 1 | 99 | 57 |
| 1 | 99 | 57 |
| 2 | 228 | 57 |
| 2 | 228 | 57 |
+----------+----------------+-----------------+
半正确的查询产生
+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
| 1 | 99 | 57 |
| 1 | 99 | 57 |
| 2 | 228 | 57 |
| 2 | 228 | 57 |
+----------+----------------+-----------------+
虽然不正确的查询在其结果集中没有pagelet_shingle = 57
我想要的结果是
+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
| 1 | 99 | 57 |
| 2 | 228 | 57 |
+----------+----------------+-----------------+
每次只发生一次。
将省略在同一pagelet_serial中出现两次的pagelet_shingle。
所以我想问下列内容: 1)有没有办法加快csemi或正确的查询,以达到不正确的速度 2)或者有没有办法解决不正确的问题以产生正确的结果(我不关心严格性)
答案 0 :(得分:0)
SELECT DISTINCT p.* ...
之类的声音将是您的选择。
P.S。我真的推荐第二个!让一切变得缓慢(就像你刚才注意到的那样),并且只应在必要时使用。
答案 1 :(得分:0)
此查询不能解决您的问题吗?
SELECT dt1.* FROM
(SELECT DISTINCT * FROM PAGELETS
GROUP BY page_key, pagelet_shingle HAVING COUNT(*) = 1)
dt1 JOIN
(SELECT * FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(*) > 1)
dt2 USING (pagelet_shingle) GROUP BY pagelet_shingle
答案 2 :(得分:0)
什么是
SELECT * FROM PAGELETS GROUP BY pagelet_serial, pagelet_shingle HAVING COUNT(*) > 0
给你?
答案 3 :(得分:0)
使用GROUP BY和HAVING,例如
SELECT *
FROM `pagelets`
GROUP BY `pagelet_shingle`
HAVING COUNT(*) > 1
另外你可以做一个自连接来输出所有列,不过在mysql中它应该以那种方式工作(与SQL标准不同)
答案 4 :(得分:0)
从我读到的内容来看,你在寻找的是:
SELECT DISTINCT p1.page_key, p1.pagelet_serial, p1.pagelet_shingle
FROM PAGELETS p1
JOIN PAGELETS p2 ON p2.page_key = p1.page_key
AND p2.pagelet_serial = p1.pagelet_serial
AND p2.pagelet_shingle <> p1.pagelet_shingle
该查询将充分利用(page_key, pagelet_serial)
上的索引,并且应该在十分之一秒内完成,而不是几秒钟。
如果这不是您想要的,请告诉我们如果您的表中的值是:(1,2,3),(1,2,3),(1,1),您会得到什么结果,3),(1,1,3),(1,2,4),(1,2,4),(1,1,4-),(1,1,4-)
答案 5 :(得分:0)