选择有限数量的不同行

时间:2013-11-27 22:58:46

标签: php mysql sql performance

我有一个这种格式的表:

Name     | Description    | option_id
"Apple"  | "Sweet fruit"  | 3
"Apple"  | "Sour fruit"   | 4
"Pear"   | "Sweet fruit"  | 5
"Orange" | "Orange fruit" | 3
"Carrot" | "Vegetable"    | 3

我运行查询SELECT * FROM table WHERE Description LIKE '%fruit%'并获取此信息:

Name     | Description    | option_id
"Apple"  | "Sweet fruit"  | 3
"Apple"  | "Sour fruit"   | 4
"Pear"   | "Sweet fruit"  | 5
"Orange" | "Orange fruit" | 3

我想只获得2个不同的水果名称,因此查询的结果应为:

Name     | Description    | option_id
"Apple"  | "Sweet fruit"  | 3
"Apple"  | "Sour fruit"   | 4
"Orange" | "Orange fruit" | 3

但我显然没有得到3条记录,因为使用ORDER BY Name ASC LIMIT 2会导致查询在准备好2条记录时停止。

我希望尽可能多地生成记录,只要它们的名字在前10个不同的记录中。 这是我到目前为止所得到的:

SELECT * FROM table WHERE Name IN (
    SELECT DISTINCT Name ORDER BY Name ASC LIMIT 2
) ORDER by option_id ASC

有没有更好的方法来做到没有嵌套?查询应该尽可能快。

P.S。为了使问题复杂化,这不是我的完整查询,而只是它的一部分。完整的,它看起来像这样(没有LIMIT):

SELECT table.*,
    MATCH (Name, Description) AGAINST ('fruit') AS relevance,
    MATCH (Name) AGAINST ('fruit') AS name_relevance
FROM table
WHERE MATCH (Name, Description) AGAINST ('fruit')
GROUP BY Name
ORDER BY name_relevance DESC, relevance DESC, Name ASC

我姓名不仅仅是一个名字,还有一些关于它的信息,例如“Fresh Green Apple”,“Apple Fruit”等。

2 个答案:

答案 0 :(得分:2)

无论如何,您需要获取您正在接受的名称列表。像你一样在子查询中执行此操作可能是最简单的。

您也可以使用临时表,这可能会加快这一点。

也许尝试比较这两个。我怀疑使用更大的桌子时第二个会更快。

这是一个与我相信的基本相同的

WITH fruit AS (SELECT TOP 2 DISTINCT Name FROM table1 WHERE Description LIKE '%fruit%' ORDER BY Name ASC)

SELECT * FROM table WHERE Name IN (
    SELECT * FROM fruit
) ORDER by option_id ASC

这个使用Temp表

Create TABLE #fruit (Name NVARCHAR(50))
INSERT INTO #fruit
SELECT TOP 2 DISTINCT Name FROM table1 WHERE Description LIKE '%fruit%' ORDER BY Name ASC

SELECT * FROM table WHERE Name IN (
    SELECT * FROM #fruit
) ORDER by option_id ASC

编辑MySQL

这是MySQL的TempTable解决方案

CREATE TEMPORARY TABLE fruit
SELECT DISTINCT Name FROM table1 WHERE Description LIKE '%fruit%' ORDER BY Name ASC LIMIT 2

SELECT * FROM table WHERE Name IN (
    SELECT * FROM fruit
) ORDER by option_id ASC

编辑以使用加入

保持上述性能提升,但可能值得测试。

CREATE TEMPORARY TABLE fruit
SELECT DISTINCT Name, order FROM table1 WHERE Description LIKE '%fruit%' ORDER BY Name ASC LIMIT 2

SELECT * FROM table t
JOIN fruit f ON t.Name = f.Name
ORDER by f.order

答案 1 :(得分:1)

这是一个可以证明更快的替代方案:

SELECT a.* 
FROM table1 a
JOIN (SELECT DISTINCT Name 
      FROM table1
      WHERE Description LIKE '%fruit%'
      ORDER BY Name ASC LIMIT 2)b
 ON a.Name = b.Name

演示:SQL Fiddle