2012-09-22 121 views
1

我在mytable中有一個字段容量。從最小到最大排序

我要排序的容量從最小到最大

抓取數據,這些值是

6" x 12" 
6" x 12" 
6" x 18" 
6" x 12" 
10" x 20" 
12" x 24" 

我想,如果我使用此查詢

導致

6" x 12" 
6" x 12" 
6" x 12" 
6" x 18" 
10" x 20" 
12" x 24" 

select * from mytable order by capacity ASC 

比結果是

10" x 20" 
12" x 24" 
6" x 12" 
6" x 12" 
6" x 12" 
6" x 18" 

,如果我使用此查詢

select * from mytable order by capacity + 0 ASC 

比結果是,你可以做

6" x 12" 
6" x 12" 
6" x 18" 
6" x 12" 
10" x 20" 
12" x 24" 
+0

它們是否以字符串形式存儲?什麼是列名和東西,所以我可以爲你寫一個腳本,如果你願意? –

+0

是否可以編輯表格?如果可能的話,你可能會發現使用兩個數字列來存儲這些數據比使用一個字符串更好。 – jmilloy

+0

容量字段爲varchar(255) –

回答

1

一種方式,它是遍歷的結果,並乘各價值在一起。之後使用自定義排序,你可以得到你正在尋找的結果。

$sortedArray = array(); 
$array  = array(
    '6" x 12"', '6" x 18"', '6" x 12"', '6" x 12"', '10" x 12"' 
); 

// loop through rowset 
foreach ($array as $row) { 
    $parts = explode(' x ', str_replace('"', '', $row)); 
    $sortedArray[][($parts[0] * $parts[1])] = $row; 
} 

// custom sort - PHP 5.3 required for anonymous functions 
usort($sortedArray, function($a, $b) { 
    return (array_keys($a) > array_keys($b)); 
}); 

另外,如果你沒有PHP 5.3,那麼你可以簡單地改變這樣的usort:

function mySort($a, $b) 
{ 
    return (array_keys($a) > array_keys($b)); 
} 

usort($sortedArray, 'mySort'); 
1

改變這個查詢

select * from mytable order by capacity ASC 

select * from mytable order by trim(capacity) ASC 

兩天前還幫了我.. 。

3

你應該試試這個...

SELECT *, SUBSTRING_INDEX(capacity, 'x', 1) AS width, 
    SUBSTRING_INDEX(capacity, 'x', -1) AS height 
FROM mytable 
ORDER BY width+0 ASC, height+0 ASC 
1

如果不能重構數據庫的大小存儲在兩個數值列,但要實現排序在mysql中,而在PHP後處理,你可以嘗試提取的尺寸和投值到數字,像

SELECT dimensions 
FROM mytable 
ORDER BY 
    CAST(SUBSTRING_INDEX(dimensions, '"', 1) AS SIGNED) * 
    CAST(SUBSTRING_INDEX(LEFT(dimensions, LENGTH(dimensions)-1), ' ', -1) AS SIGNED) 
    ASC 

或者,更好的,類似阿什維尼的回答是:

SELECT dimensions 
FROM mytable 
ORDER BY 
    (SUBSTRING_INDEX(dimensions, 'x', 1) + 0) * 
    (SUBSTRING_INDEX(dimensions, 'x', -1) + 0) 
    ASC 

您可能需要調整兩個子字符串索引部分。

另一種方式來提取您需要的值:

  • 提取物中的第一個維度(從開始到第一個「子字符串:LEFT(dimensions, INSTR(dimensions, '"'))

  • 提取第二尺寸(子從後在x爲1小於結束):右(左(尺寸,長度(尺寸-1)),INSTR(尺寸, 'X')+ 1)

4

這是表格的非常糟糕的模式。最好的方法是創建一個表格,將它們分開()爲兩列:寬度高度。例如,

CREATE TABLE Dimension 
(
    ID INT AUTO_INCREMENT, 
    `Width` INT, 
    `Height` INT, 
    CONSTRAINT tb_pk PRIMARY KEY (ID) 
); 

,那麼你現在可以插入你的記錄是這樣,

INSERT INTO Dimension (`Width`, `Height`) VALUES (6, 12), (6,18), (10, 12); 

,只需使用該查詢命令的結果

SELECT * 
FROM Dimension 
ORDER BY (`width` * `height`) DESC 

但是,爲了回答你的問題在不更改架構的情況下,在您的服務器中創建USER DEFINE FUNCTION

CREATE FUNCTION SPLIT_STR 
(
    x VARCHAR(255), 
    delim VARCHAR(12), 
    pos INT 
) 
RETURNS VARCHAR(255) 
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), 
     LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), 
     delim, ''); 

然後使用此查詢,如果你能

SELECT CAST(SPLIT_STR(REPLACE(`capacity`, '"', '') ,'x', 1) as SIGNED) width, 
     CAST(SPLIT_STR(REPLACE(`capacity`, '"', '') ,'x', 2) as SIGNED) height 
FROM tableName 
ORDER BY (width * height) DESC 

SQLFiddle Demo

+2

這真的是最好的答案。如果絕對不可能更改表的模式,則只使用其他答案之一。 – jmilloy

+0

@jmilloy我不同意。這是最好的_solution_,但不是最好的_answer_。這不一樣。很多時候,OP沒有訪問權,時間等來進行類似John Woo建議的改變。 –

+0

@John Woo爲什麼你創建一個函數SPLIT_STR而不是使用SUBSTRING_INDEX? – jmilloy

1

做人情爲你的自我。此數據與SQL創建2 separete列,如果你不想來連接在PHP中值,contactenate:

select contact(width, '" x ', height, '"') as capacity from mytable order by width asc, height asc 

此外,通過排序寬度和高度separatelly更加eficient併產生期望的結果。