我需要显示由某个数字列排序的数据库表中的记录列表。该表如下所示:
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数据库中的示例都可以。
由于
答案 0 :(得分:2)
您确定要在SQL中执行此操作吗?
对我而言,这听起来应该将结果加载到某种数据集中,然后根据需要重新排序,或者将起点定位在正确的位置。
可能使用链表。
答案 1 :(得分:2)
了解这对您有何帮助。使用通用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
答案 2 :(得分:1)
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 i ORDER BY position)AS s WHERE s.position = items.position)%(SELECT COUNT(*)FROM items)
答案 3 :(得分:1)
我在这里正在讨论海滩的解决方案,但是取消了自连接,只选择 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
;
答案 4 :(得分:0)
如果它是一个设置列表,您知道可以执行以下操作的项目数:
SELECT *
FROM Items
ORDER BY CASE WHEN Position >= Position THEN POSITION ELSE Position+1000 END
但它真的很难看。
答案 5 :(得分:0)
这在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(没有全部)会重新排序结果,因为它会查找重复项
答案 6 :(得分:0)
根据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是一个任意数字,高于你可能拥有的任何结果数。
我仍然不完全相信这在实践中会比重新排列网络服务器上的列表更快......我想,这将完全取决于你如何处理结果集以及它有多大。但至少它避免了海滩聪明方法中的自我交叉加入。