MySQL在“批处理”中排序不同

时间:2011-07-04 14:11:13

标签: mysql sql

下面是按重序排序权重的标准查询。

SELECT * FROM article ORDER BY weight DESC LIMIT 0, 4
+-------------+--------+
| title       | weight |
+-------------+--------+
| B           | 2      | 
| E           | 2      | 
| Y           | 2      | 
| A           | 1      | 
| C           | 1      | 
| D           | 1      | 
| F           | 1      | 
| G           | 1      | 
| X           | 1      | 
| Z           | 1      | 
| I           | 1      | 
| G           | 1      | 
+-------------+--------+

但是,我希望根据权重值对其进行不同的排序。

+-------------+--------+
| title       | weight |
+-------------+--------+
| B           | 2      | 
| A           | 1      | 
| C           | 1      | 
| D           | 1      | 
| E           | 2      | 
| F           | 1      | 
| G           | 1      | 
| X           | 1      | 
| Y           | 2      | 
| Z           | 1      | 
| I           | 1      | 
| G           | 1      | 
+-------------+--------+

重量值为2的记录仅选择一次并在顶部排序。然后是重量值为1的记录。

2 个答案:

答案 0 :(得分:1)

使用这些答案中的方法:

对于权重值为2的行和具有任何其他权重值的行,您可以单独获取行号,然后使用生成的数字进行排序。

在我继续之前,请注意,即使official documentation承认

  

您可能会得到您期望的结果,

它也建议,

  

作为一般规则,您不应该为用户变量赋值并在同一语句中读取值。

(由相同的陈述表示SET以外的陈述。)

以下是获取预期订单的方法如果结果符合预期。

SET @row2 = -1;
SET @row_other = -1;

SELECT
  title, weight
FROM (
  SELECT
    title, weight,
    @row2 := @row2 + CASE weight WHEN 2 THEN 1 ELSE 0 END AS weight2_row,
    @row_other := @row_other + CASE weight WHEN 2 THEN 0 ELSE 1 END AS other_weight_row
  FROM article
) s
ORDER BY
  CASE weight WHEN 2 THEN @row2 ELSE @row_other DIV 3 END,
  weight = 2 DESC

Weight=2行的具体顺序未定义,就像您提出的问题一样。

答案 1 :(得分:1)

采取Andriy所述的相同预防措施,您也可以使用:

SELECT title, weight
FROM
    ( SELECT title, weight
           , @rownumber2 := @rownumber2 + 3 AS rn
      FROM article
         , ( SELECT @rownumber2 := 1 ) AS dummy
      WHERE weight = 2
      ORDER BY title                     --- optional, configure it for the 
                                         --- ordering of rows with weight = 2
    UNION ALL

      SELECT title, weight
           , @rownumber1 := @rownumber1 + 1 AS rn
      FROM article
         , ( SELECT @rownumber1 := 3 ) AS dummy
      WHERE weight = 1
      ORDER BY title DESC                --- optional, configure it for the 
                                         --- ordering of rows with weight = 1
    ) AS insaneOrdering

ORDER BY rn
       , weight DESC ;