从表中选择特定行

时间:2017-06-26 17:14:44

标签: sql-server

我在引号表中有以下几个字段: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行?

3 个答案:

答案 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