[英]Special order by on SQL query
我需要顯示由某個數字列排序的數據庫表中的記錄列表。 該表如下所示:
CREATE TABLE items (
position int NOT NULL,
name varchar(100) NOT NULL,
);
INSERT INTO items (position, name) VALUE
(1, 'first'),
(5, 'second'),
(8, 'third'),
(9, 'fourth'),
(15, 'fifth'),
(20, 'sixth');
現在,列表的順序應根據用戶提供的參數而改變。 此參數指定首先出現的記錄如下:
position = 0
order should be = 1, 5, 8, 9, 15, 20
position = 1
order should be = 20, 1, 5, 8, 9, 15
position = 2
order should be = 15, 20, 1, 5, 8, 9
換句話說,最后一條記錄成為第一條,依此類推。 你能想到在SQL中這樣做的方法嗎?
我正在使用MySQL,但任何SQL數據庫中的示例都可以。
謝謝
您確定要在SQL中執行此操作嗎?
對我來說,這聽起來應該將結果加載到某種數據集中,然后根據需要重新排序,或者將起點定位在正確的位置。
可能使用鏈表。
看看這對你有什么用。 使用通用SQL,因此它對MySql(未經測試)也應該有效。
DECLARE @user_sort INTEGER
SET @user_sort = 0
SELECT position, name FROM
(
SELECT I1.position, I1.name, COUNT(*) AS rownumber, (SELECT COUNT(*) FROM items) AS maxrows
FROM items I1, items I2
WHERE I2.position <= I1.position
GROUP BY I1.position, I1.name
) Q1
ORDER BY
CASE WHEN maxrows - rownumber < (@user_sort % maxrows) THEN 1 ELSE 2 END, position
注意:*如果用戶提供的排序索引大於行計數,則該值將換行到有效范圍內。 要刪除此功能,請從ORDER BY中刪除“%maxrows”。
結果:
SET @user_sort = 0
position name
1 first
5 second
8 third
9 fourth
15 fifth
20 sixth
SET @user_sort = 1
position name
20 sixth
1 first
5 second
8 third
9 fourth
15 fifth
SET @user_sort = 2
position name
15 fifth
20 sixth
1 first
5 second
8 third
9 fourth
SET @user_sort = 9
9 fourth
15 fifth
20 sixth
1 first
5 second
8 third
ORDER BY(FIELD(位置,1,5,8,9,15,20)+參數)%7
編輯:為了讓花生畫廊快樂,一般的解決方案是:
ORDER BY(SELECT ix + parameter - 1 FROM(SELECT i.position,@ ix = = @ix + 1 AS ix FROM(SELECT @ix:= 0)AS n,items AS ORDER BY position)AS s WHERE s。 position = items.position)%(SELECT COUNT(*)FROM items)
我在這里對海灘的解決方案不屑一顧,但是消除了自連接,只從items表中選擇了兩次(並使用了Oracle語法):
select
i.position
, i.name
from(
select
items.*
, ( SELECT COUNT(*) FROM items ) AS maxrows
from items
order by position
) i
order by
case
when rownum > maxrows - 2 -- NOTE: change "2" to your "position" variable
then 1 - 1 / rownum -- pseudo-rownum < 1, still ascending
else
rownum
end
;
如果它是一個設置列表,您知道可以執行以下操作的項目數:
SELECT *
FROM Items
ORDER BY CASE WHEN Position >= Position THEN POSITION ELSE Position+1000 END
但它真的很難看。
這真的不是在SQL中做的理想事情。
我有解決方案,但是對於大型表格,它會很慢。
DECLARE @iOrder INT
SET @iOrder = 4
SELECT abc.position,abc.name FROM
(
SELECT position,name,ROW_NUMBER() OVER (ORDER BY position) AS rownum
FROM items
) abc
WHERE abc.rownum >= @iOrder
UNION ALL
SELECT def.position, def.name FROM
(
SELECT position,name,ROW_NUMBER() OVER (ORDER BY position) AS rownum
FROM items
) def
WHERE def.rownum < @iOrder
請注意,使用UNION(沒有全部)將重新排序結果,因為它將查找重復項
根據John的評論,但是使用LIMIT語法(ROW_NUMBER / OVER在MySQL中不起作用,除了LIMIT更容易閱讀):
(
SELECT position, name FROM items
ORDER BY position
LIMIT @offset, @bignum
) UNION ALL (
SELECT position, name FROM items
ORDER BY position
LIMIT @offset
)
其中@bignum是一個任意數字,高於你可能擁有的任何數量的結果。
我仍然不完全相信這在實踐中會比重新安排網絡服務器上的列表更快...這將完全取決於你如何處理結果集以及它有多大,我想。 但至少它避免了海灘聰明方法中涉及的自我交叉加入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.