【问题标题】:Why outer order by does not work correctly?为什么外部顺序不能正常工作?
【发布时间】:2016-01-15 10:01:13
【问题描述】:

我有一个这样的查询:

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 列,结果也是两个表的交替。 p>

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

【问题讨论】:

  • 这些查询在我看来完全不同。在一种情况下,您递增“2”,而在另一种情况下,您递增“3”。因此,排名会有所不同。也许您应该解释一下您要做什么。
  • 好的我想要这个:第一个查询的焦点:第一个查询 select 和第二个 select 返回一些重复的行,现在我想防止这种情况(在这种情况下 UNION DISTINCT 像 @987654332 @)。另外我想我可以写一个select,而不是两个第一个select(因为表名是相同的)。我的目的完全是排序。我想在结果顶部显示第一个 select 的结果。
  • 我更愿意看到原始数据源和预期结果集,而不是所有这些奇怪的查询 :-)
  • @GordonLinoff 顺便说一句,我使用rank 对结果进行交替排序。所以我肯定需要用2 替换它,因为我删除了一个select 子句。
  • @Alex 好的,我会添加一些表格..

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


【解决方案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") 条件的记录可能经常出现两次(但排名值不同)。

【讨论】:

  • :-) !这个查询有点复杂,我测试了一下,它的排序几乎正确,很好。但它的持续时间超过了我的第一个查询(三个select 子句)。不管怎样,谢谢。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 2019-01-04
  • 2020-09-03
  • 2016-10-10
  • 2016-10-24
相关资源
最近更新 更多