2011-02-17 137 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) 

而且,除了額外的輸出列,這正是你要求它做的事。

相關問題