2011-02-17 91 views
1
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 

这是另一个我以前发布的问题的场景。MySQL - PERL - 按多列排序,然后按列零件编号字段排序

请注意,我实际上是使用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为分页/导航。

(该表有更多的数据结果真的被压入的阵列,因为有一些交叉引用/查询到后来其他表回事下来的代码。)

肯定是一个大问题,其中有人可能在这里简单回答你'去!

感谢您帮助这个菜鸟大家。

回答

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 

联盟本质上都需要查询的输出和连接它们。

+0

我会尽力回复你。看起来有希望我会在UNION ALL上做一些阅读。谢谢你指点我。如果这对我有用,我会选择你的答案。 – Stephie 2011-02-17 14:56:58

+0

@Dodger指出了一个重要的问题,where子句需要> 0而不是> 1。 – 2011-02-17 19:26:52

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 
+0

这不会产生与他现在运行的3个查询相同的效果。它将改变显示数据的顺序,因为它只会按pnumber排序,发布者需要按子类别排序,然后按pnumber排序。 – 2011-02-17 14:36:04

0

我看到与您的示例数据有一些不一致之处。您正在寻找具有特殊值,有限值或正常值的值大于1的东西,但您的示例数据集只有值为1.您永远不会从此数据集中获得任何结果,因为没有任何匹配的WHERE子句。

此外,您指定ORDER BY子句与DESC,但你希望看到的结果的例子,你给他们排序与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示例之一,那么在特殊情况下> 0 AND限制时间> 0的情况下,你会得到一个重复的输出行,因为它可以匹配多个UNION-ed查询。

下面的查询将输出以下,在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) 

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

相关问题