MySQL - PERL - 按多列排序,然后按列部件号字段排序

时间:2011-02-17 14:05:33

标签: mysql perl sorting

id|pnumber|special|limitedtime|normal
1 |765234 |1      |0          |0
2 |765235 |0      |1          |0
3 |776234 |0      |0          |1
4 |776235 |1      |0          |0
5 |785456 |0      |1          |0
6 |785457 |1      |0          |0

以下是我之前发布的问题的另一种情况。

请注意我实际上使用dbi和占位符,但仅使用我的问题的基础知识。

而不是三个查询:

SELECT `pnumber` from `table`
WHERE `special` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar2

执行并显示

SELECT `pnumber` from `table`
WHERE `limitedtime` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar2

执行并显示

SELECT `pnumber` from `table`
WHERE `normal` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar2

执行并显示

这给出了我的结果但是,LIMIT需要与所有三个/依赖关系相关联。

所以,我想做类似的事情:

SELECT `pnumber` from `table`
ORDER BY special?? ABS(pnumber) DESC,
ORDER BY limitedtime?? ABS(pnumber) DESC,
ORDER BY normal?? ABS(pnumber) DESC
LIMIT $Lvar1,$Lvar2

我认为,如果做得正确,我会按照我想要的顺序给我结果。

765234 (special)
776235 (special)
785457 (special)
765235 (limitedtime)
785456 (limitedtime)
776234 (normal)

我使用LIMIT $ Lvar1,$ Lvar2进行分页/导航。

(该表有更多的数据结果实际上被推送到数组中,因为在代码的后面有一些交叉引用/查询到其他表。)

当然是一个很大的问题,有人可以在这里简单地回答你的问题!

感谢大家帮助这个菜鸟。

3 个答案:

答案 0 :(得分:1)

您可以使用union all来组合查询的输出

SELECT `pnumber` from `table`
WHERE `special` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar2

UNION ALL

SELECT `pnumber` from `table`
WHERE `limitedtime` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar

UNION ALL

SELECT `pnumber` from `table`
WHERE `normal` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar

Union All主要获取查询的输出并连接它们。

答案 1 :(得分:1)

您可以使用union运算符加入三个选择,然后执行顺序和限制。

SELECT `pnumber` from `table`
WHERE `special` > 1
union
SELECT `pnumber` from `table`
WHERE `limitedtime` > 1
union
SELECT `pnumber` from `table`
WHERE `normal` > 1
ORDER BY ABS(pnumber) DESC 
LIMIT $Lvar1,$Lvar2

答案 2 :(得分:0)

我发现您的示例数据存在一些不一致之处。您正在寻找具有值> gt的特殊,有限时间或正常的事物。 1,但您的示例数据集只有值1.您根本不会从此数据集中获得任何结果,因为没有任何内容与WHERE子句匹配。

此外,您正在使用DESC指定ORDER BY子句,但在您希望将其视为结果的示例中,您将显示它们以pnumber升序排序。

我将在这里做两个假设:

1)你真的想要它们的值是> 0,不是> 1(如果你只需要一个非零值,查询会变得更简单,但由于你专门使用了ABS(),我假设你正在使用的真实数据可以是负数值。)

2)你实际上是指ASC,而不是DESC,因为你要求的输出是按顺序排列的。

因此,使用您在上面指定的数据,以下查询将起作用:

  SELECT pnumber,
         CONCAT('(',
                CONCAT_WS(', ',
                          IF(special > 0, 'special', NULL),
                          IF(limitedtime > 0, 'limited time', NULL),
                          IF(normal > 0, 'normal', NULL)),
                ')') AS type_desc,
         IF(special > 0, 3, 0) + IF(limitedtime > 0, 2, 0) + IF(normal > 0, 1, 0) AS disp_priority
    FROM ex_table
   WHERE ((special > 0) + (limitedtime > 0) + (normal > 0)) > 0
ORDER BY disp_priority DESC,
         ABS(pnumber) ASC

不需要UNION。另请注意,UNION可能无法提供您正在寻找的内容:如果您使用上面显示的UNION示例之一,那么在两个特殊的> 0和限制时间> 0你会得到一个重复的输出行,因为它会匹配多个UNION编辑的查询。

下面的查询在MySQL监视器中输出以下内容:

+---------+----------------+---------------+
| pnumber | type_desc      | disp_priority |
+---------+----------------+---------------+
|  765234 | (special)      |             3 | 
|  776235 | (special)      |             3 | 
|  785457 | (special)      |             3 | 
|  765235 | (limited time) |             2 | 
|  785456 | (limited time) |             2 | 
|  776234 | (normal)       |             1 | 
+---------+----------------+---------------+
6 rows in set (0.23 sec)

而且,除了额外的输出列,这正是你要求它做的。