MySQL在多列中排名最低

I have a table with the following:

+----+-------+-------+-----------+-----------+--------------+--------------+
| id | stock | price | usedStock | usedPrice | specialStock | specialPrice |
+----+-------+-------+-----------+-----------+--------------+--------------+
| #1 |     1 | 10.00 |         0 | 0         |            0 | 0            |
| #2 |     0 | 0     |         1 | 15.00     |            1 | 20.00        |
| #3 |     0 | 0     |         0 | 11.00     |            1 | 14.00        |
+----+-------+-------+-----------+-----------+--------------+--------------+

I would like to create a query that orders by lowest price first if the type of item is in stock.

So the query would result in the following order:

#1 - 10.00 (because 10.00 is the lowest result)
#3 - 14.00 (because although 11.00 is less, it's not in stock)
#2 - 15.00 (because 15.00 is lower than 20.00)

I've added the PHP tag to this question in case there's a quicker way of calculating using PHP after selecting the table.

I would order by the least price, in case item is present in stock:

ORDER BY
  LEAST(CASE WHEN stock        THEN price        ELSE GREATEST(price, usedPrice, specialPrice) END,
        CASE WHEN usedStock    THEN usedPrice    ELSE GREATEST(price, usedPrice, specialPrice) END,
        CASE WHEN specialStock THEN specialPrice ELSE GREATEST(price, usedPrice, specialPrice) END)

If the condition is true (>=1), each CASE WHEN will return the price, otherwise it will return the greatest price. Fiddle here.

I would create a view first

CREATE VIEW stock_min_price AS
SELECT id, LEAST(IF(stock > 0, price, 1000000000),
    IF (usedStock > 0, usedPrice, 10000000000),
    IF (specialStock > 0, specialPrice, 10000000000)) AS actualPrice
FROM tablename;

then select and order by actual price of all items

SELECT id, IF(actualPrice = 1000000000, NULL, actualPrice) AS price
FROM stock_min_price
ORDER BY actualPrice

//edit: comparing to > 0 when stock can be greater than 1

Frankly, you should rethink your Data Modeling for exactly this kind of operation. There is no direct connection between the three types of stock, so you really should normalize them into another Table. For this i am going to assume your old table is named oldTable

    CREATE TABLE stock(item_id integer, amount integer, price double, type enum('normal', 'used', 'special'));

    INSERT INTO stock SELECT o.id, o.stock, o.price,'normal' FROM _oldTable as o 
    WHERE o.stock >0 OR o.amount >0 ;

    INSERT INTO stock SELECT o.id, o.usedStock, o.usedPrice, 'used' FROM _oldTable as o
    WHERE o.stock >0 OR o.amount >0 ;

    INSERT INTO stock SELECT o.id, o.specialStock, o.specialPrice,'special' FROM _oldTable as o
    WHERE o.stock >0 OR o.amount >0 ;

And there you have it. As you can see you can now basically get your information with a simple join on the stock table.

    SELECT o.id, s.kind, min(s.price) FROM _oldTable_ AS o 
    JOIN stock as s ON s.item_id = o.id AND s.amount > 0
    GROUP BY s.item_id

If you want to produce an output like in your original Table you use:

    SELECT o.id, n.amount as amount, n.price as price, u.amount as usedAmount, u.price as usedPrice, s.amount as specialAmount, s.price as specialPrice
    FROM _oldTable_ AS o 
    LEFT JOIN stock as n ON n.item_id = o.id AND n.type = 'normal'
    LEFT JOIN stock as u ON u.item_id = o.id AND n.type = 'used'
    LEFT JOIN stock as s ON s.item_id = o.id AND n.type = 'special';

It is now also more easy to a) get the total amount for each in stock (sum on the amount column with a GROUP BY Statement for the item_id) b) get the kind of stock that is used.

p.s.: you should probably set an index on the item_id column if you have lots of items. Also note that this solution potentially saves you disc space if not all items have all kinds of stock