我在引号表中有以下几个字段:quotesid是主键
+----------+----------------+-----------------------+
| QuotesID | QuotesDesc | QuotesAuthor |
+----------+----------------+-----------------------+
| 300 | my first quote | william whakespeare |
| 301 | my second quote | william shakespeare |
| 302 | my third quote | william shakespeare |
| 303 | my 4th quote | william shakespeare |
| 304 | my fifth quote | william shakespeare |
| 305 | my sixth quote | william shakespeare |
| 402 | my seventh quote | william shakespeare |
| 412 | my eighth quote | william shakespeare |
+----------+----------------+-----------------------+
我有一个像select * from quotestable where QuotesAuthor ='william shakespeare'
这样的查询。
我的要求是在我的网页上,如果我显示报价为quote = 300的报价,我希望接下来的6个报价显示在iframe中。即,301,302,303,304,305,402。
如果我的网页显示引号= 304,我希望接下来的6个引号为305,402,412,300,301,302(如果它从头开始结束)
是否有查询可以为我提供所有必需的6行?
答案 0 :(得分:1)
DECLARE @QuotesID INT = 304;
DECLARE @Table1 TABLE
([QuotesID] int, [QuotesDesc] varchar(14), [QuotesAuthor] varchar(18));
INSERT INTO @Table1
([QuotesID], [QuotesDesc], [QuotesAuthor])
VALUES
(300, 'myfirstquote', 'williamshakespeare'),
(301, 'mysecondquote', 'williamshakespeare'),
(302, 'mythirdquote', 'williamshakespeare'),
(303, 'my4thquote', 'williamshakespeare'),
(304, 'myfifthquote', 'williamshakespeare'),
(305, 'mysixthquote', 'williamshakespeare'),
(402, 'myseventhquote', 'williamshakespeare'),
(412, 'myeighthquote', 'williamshakespeare');
SELECT QuotesID
, QuotesDesc
, QuotesAuthor
, ISNULL(( SELECT TOP (1) QuotesID
FROM @Table1 AS T2
WHERE T2.QuotesAuthor = T1.QuotesAuthor
AND T2.QuotesID > T1.QuotesID
ORDER BY QuotesID ASC)
, MIN(QuotesID) OVER (PARTITION BY T1.QuotesAuthor)) AS NextQuotesID
, ISNULL(( SELECT TOP (1) QuotesID
FROM @Table1 AS T3
WHERE T3.QuotesAuthor = T1.QuotesAuthor
AND T3.QuotesID < T1.QuotesID
ORDER BY QuotesID DESC)
, MAX(QuotesID) OVER (PARTITION BY T1.QuotesAuthor)) AS PrevQuotesID
FROM @Table1 AS T1
CROSS APPLY (SELECT CASE WHEN QuotesID >= @QuotesID THEN 0 ELSE 1 END AS OrderColumn) AS T
WHERE QuotesAuthor = 'williamshakespeare'
ORDER BY OrderColumn, QuotesID;
查询的工作原理如下:ORDER BY
会检查订购方式,如果QuotesID
等于或高于您当前的@QuotesID
,它会先排名,如果他们'小于@QuotesID
,它们将排在第二位,然后按升序排序QuotesID
。
@QuotesID = 304
;
+----------+----------------+--------------------+--------------+--------------+
| QuotesID | QuotesDesc | QuotesAuthor | NextQuotesID | PrevQuotesID |
+----------+----------------+--------------------+--------------+--------------+
| 304 | myfifthquote | williamshakespeare | 305 | 303 |
| 305 | mysixthquote | williamshakespeare | 402 | 304 |
| 402 | myseventhquote | williamshakespeare | 412 | 305 |
| 412 | myeighthquote | williamshakespeare | 300 | 402 |
| 300 | myfirstquote | williamshakespeare | 301 | 412 |
| 301 | mysecondquote | williamshakespeare | 302 | 300 |
| 302 | mythirdquote | williamshakespeare | 303 | 301 |
| 303 | my4thquote | williamshakespeare | 304 | 302 |
+----------+----------------+--------------------+--------------+--------------+
答案 1 :(得分:1)
编辑:我错过了你问题的最后一部分,如果你到达目的地,你说要重新开始。如果你想要返回的第一行以及后面的6,我有点不清楚,但如果不是只是将它从前7改为前6。这个查询比其他答案容易一点,并避免了SELECT中的查询条款和交叉申请。
DECLARE @Quotes TABLE (
QuotesID INT,
QuotesDesc VARCHAR(30),
QuotesAuthor VARCHAR(30));
INSERT INTO @Quotes
(QuotesID, QuotesDesc, QuotesAuthor)
VALUES
(300, 'my first quote', 'William Shakespeare'),
(301, 'my second quote', 'William Shakespeare'),
(302, 'my third quote', 'William Shakespeare'),
(303, 'my 4th quote', 'William Shakespeare'),
(304, 'my fifth quote', 'William Shakespeare'),
(305, 'my sixth quote', 'William Shakespeare'),
(402, 'my seventh quote', 'William Shakespeare'),
(412, 'my eighth quote', 'William Shakespeare');
DECLARE @QuotesID INT = 304;
DECLARE @Author varchar(24) = 'William Shakespeare';
SELECT TOP 7
*
FROM (
select TOP 7 *
from @Quotes T1
where T1.QuotesAuthor = @Author
AND T1.QuotesID >= @QuotesID
order by T1.QuotesID
UNION ALL
SELECT TOP 7 *
FROM @Quotes T2
WHERE T2.QuotesAuthor = @Author
AND T2.QuotesID < @QuotesID
ORDER BY T2.QuotesID
) X
结果:
+----------+------------------+---------------------+
| QuotesID | QuotesDesc | QuotesAuthor |
+----------+------------------+---------------------+
| 304 | my fifth quote | William Shakespeare |
| 305 | my sixth quote | William Shakespeare |
| 402 | my seventh quote | William Shakespeare |
| 412 | my eighth quote | William Shakespeare |
| 300 | my first quote | William Shakespeare |
| 301 | my second quote | William Shakespeare |
| 302 | my third quote | William Shakespeare |
+----------+------------------+---------------------+
答案 2 :(得分:1)
另一个更简单的方法是应用人工订单属性。
对于每个QuotesID
,我们标记id是大于还是小于我们开始的id。然后,我们按此属性对集合进行排序,然后是其他排序条件。
在这个集合中,我们采用前N个记录。
相应地更改where
子句,以便包含起始ID(无where子句)或不包括QuotesID <> 300
。
您的查询可能如下所示
select top 6
case when QuotesID < @startid then 1 else 0 end orderbit
,*
from @Quotes
where QuotesID <> 300
order by orderbit, QuotesID
一个完整的例子:
DECLARE @startid INT = 304;
DECLARE @Quotes TABLE
(QuotesID int, QuotesDesc varchar(20), QuotesAuthor varchar(20));
INSERT INTO @Quotes(QuotesID, QuotesDesc, QuotesAuthor)
VALUES
(300, 'myfirstquote', 'williamshakespeare'),
(301, 'mysecondquote', 'williamshakespeare'),
(302, 'mythirdquote', 'williamshakespeare'),
(303, 'my4thquote', 'williamshakespeare'),
(304, 'myfifthquote', 'williamshakespeare'),
(305, 'mysixthquote', 'williamshakespeare'),
(402, 'myseventhquote', 'williamshakespeare'),
(412, 'myeighthquote', 'williamshakespeare');
select top 6
case when QuotesID < @startid then 1 else 0 end orderbit
,*
from @Quotes
where QuotesID <> @startid
order by orderbit, QuotesID
导致
orderbit QuotesID QuotesDesc QuotesAuthor
----------- ----------- -------------------- --------------------
0 305 mysixthquote williamshakespeare
0 402 myseventhquote williamshakespeare
0 412 myeighthquote williamshakespeare
1 300 myfirstquote williamshakespeare
1 301 mysecondquote williamshakespeare
1 302 mythirdquote williamshakespeare