为什么外部订单不能正常工作?

时间:2015-10-16 15:21:10

标签: mysql performance sql-order-by union-all

我有这样的查询:

SELECT @rank := @rank + 3 `rank`, id, subject, name
  FROM quran, (select @rank := -2) q
     WHERE MATCH (subject, name) AGAINST ('anything') and aye IN ("10")

UNION DISTINCT

SELECT @rank1 := @rank1 + 3 `rank`, id, subject, name
  FROM quran, (select @rank1 := -1) q 
     WHERE MATCH (subject, name) AGAINST ('anything')

UNION ALL

SELECT @rank2 := @rank2 + 3 `rank`, id, subject, byA
  FROM hadith, (select @rank2 := 0) q 
     WHERE MATCH (subject) AGAINST ('anything')

ORDER BY rank LIMIT 0, 11

现在我优化了我的查询并将第一个SELECT子句合并为一个,如下所示:(因为它们具有相同的表名)

(SELECT @rank1 := @rank1 + 2 `rank`, id, subject, name
  FROM quran, (select @rank1 := -1) q 
     WHERE MATCH (subject, name) AGAINST ('anything') 
       ORDER BY CASE WHEN aye IN ('10') 
          THEN 0
          ELSE 1
       END
)

UNION ALL

(SELECT @rank2 := @rank2 + 2 `rank`, id, subject, byA
  FROM hadith, (select @rank2 := 0) q 
     WHERE MATCH (subject) AGAINST ('anything')
)

ORDER BY rank LIMIT 0, 11

但我不知道为什么这种结果与第一个查询不一致。为什么?我该如何解决?

修改:以下是一些示例:

// quran                               // hadith
+----+---------+--------+                +----+---------+-------+
| id | subject |  name  |                | id | subject |  byA  |
+----+---------+--------+                +----+---------+-------+
| 1  | hello   | jack   |                | 1  | blue    | jack  |
| 2  | blue    | peter  |                | 2  | how     | hello |
| 3  | jack    | red    |                | 3  | jack    | blue  |
| 4  | back    | blue   |                +----+---------+-------+
| 10 | jack    | how    |
+----+---------+--------+

现在,我想要输出:首先要优先$number,然后是subject列,然后是name列,结果也是交替的对于两个表。

$anything = 'jack', $number = 10
+----+---------+--------+
| id | subject |  name  |
+----+---------+--------+
| 10 | jack    | how    |
| 3  | jack    | blue   |
| 3  | jack    | red    |
| 1  | blue    | jack   |
| 1  | hello   | jack   |
+----+---------+--------+

1 个答案:

答案 0 :(得分:1)

我并不是说这是处理事情的最佳方式,但这是对现有尝试的最小修改。

(
  SELECT IF(aye IN ("10"), 0, 1) AS sortGroup
     , IF(aye IN ("10"), @rank := @rank + 3, @rank1 := @rank1 + 3) AS `rank`
     , id, subject, name
  FROM quran
     , (select @rank := -2) AS rq, (select @rank1 := -1) AS r1q  
  WHERE MATCH (subject, name) AGAINST ('anything') 
)
UNION ALL
(
  SELECT 2 AS sortGroup
     , @rank2 := @rank2 + 2 `rank`
     , id, subject, byA
  FROM hadith
     , (select @rank2 := 0) AS q 
  WHERE MATCH (subject) AGAINST ('anything')
)
ORDER BY sortGroup, rank 
LIMIT 0, 11

实际上,我不肯定你可以合并前两个联合查询并获得相同的结果。在原始查询中,UNION DISTINCT和原始版本中的排名单独计算,满足aye IN ("10")条件的记录可能经常出现两次(但具有不同的排名值)。