【问题标题】:Taking the second last row with only one select in SQL Server?SQL Server 中只有一个选择的倒数第二行?
【发布时间】:2012-01-02 04:38:34
【问题描述】:

我试图用 SQL Server 选择倒数第二行。所以我写了一个这样的查询:

SELECT TOP 1 * From Cinema 
WHERE CinemaID!=(SELECT TOP 1 CinemaID 
                 FROM Cinema
                 ORDER BY CinemaID DESC)                      
ORDER BY CinemaID DESC 

它做了我需要的。但我想只用一个选择来做同样的事情。

我读到 MySql 中的 LIMIT 子句就是这样做的。但我找不到任何等价物 那个。因此,我感谢任何有关寻找有用信息的帮助。

【问题讨论】:

  • 我喜欢你目前的解决方案。
  • LIMIT 是非 ANSI 标准的 MySQL 特定扩展 ...

标签: sql-server select


【解决方案1】:
select * from 
(select  ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) as R, * from Cinema ) T1
where (select count(*) from Cinema ) - T1.R = 1

【讨论】:

  • 嗨沙菲。欢迎来到 Stack Overflow 并感谢您的贡献。但是,即使只是一个简短的解释,您能否添加一个解释。 How to Answer。亲切的问候。
【解决方案2】:

这是我的代码:

SELECT *  From
(select * from table name ORDER BY column name  DESC LIMIT 2) AS xyz                   
ORDER BY column name LIMIT 1;

【讨论】:

  • 操作员要求只有一个 SELECT 的解决方案,但您提出的解决方案似乎使用两个 SELECT,就像他的一样
【解决方案3】:

从 sql 表中获取倒数第二行的最简单方法是用户 ORDER BY CinemaID DESC 并设置 LIMIT 1,1

试试这个

SELECT * from `Cinema` ORDER BY `CinemaID` DESC LIMIT 1,1

【讨论】:

  • 问题是关于 SQL Server 的。这个答案似乎在 SQL Server 中不起作用。
【解决方案4】:

如果你需要这样做,但是:

  • 该列不同于id
  • 您需要按特定列排序
  • 不能在 FROM 子句上使用 SELECT(例如,如果您使用的是旧版本的 Hibernate)。

你可以这样做:

select top 1 * from Cinema
where date < (select MAX(date) from Cinema)
order by date desc

【讨论】:

    【解决方案5】:

    此查询也适用于 SQLITE

    SELECT *  From
    (select * from Cinema ORDER BY CinemaID  DESC LIMIT 2) AS name                    
    ORDER BY CinemaID LIMIT 1
    

    【讨论】:

      【解决方案6】:

      由于这个(旧)问题没有被标记为特定的 SQL-Server 版本,并且没有一个(非常好的)答案只使用一个 SELECT 子句 - 因为在旧版本中不可能 -这是仅适用于最近的 2012+ 版本的版本:

      SELECT c.* 
      FROM dbo.Cinema AS c                    
      ORDER BY CinemaID DESC
      OFFSET 1 ROW
      FETCH FIRST 1 ROW ONLY ; 
      

      测试于 SQLFiddle

      【讨论】:

        【解决方案7】:
        select top 1* from(SELECT TOP 2 * From Cinema 
                           WHERE CinemaID
                           ORDER BY CinemaID DESC) XYZ
        ORDER BY CinemaID
        

        其中 XYZ 不是关键字。这只是一个词。单词可以是任何东西。

        【讨论】:

          【解决方案8】:
          select * from TABLE_NAME order by COLUMN_NAME desc limit 1,1 ;
          

          COLUMN_NAME 应该是“主键”或“唯一”

          【讨论】:

          • 问题是关于 SQL Server 的。这个答案似乎在 SQL Server 中不起作用。
          【解决方案9】:
          SELECT field_name FROM (SELECT TOP 2 field_name FROM table_name 
                                  ORDER BY field_name DESC)
          WHERE rownum = 2;
          

          【讨论】:

            【解决方案10】:
            SELECT TOP 1 * FROM tbl_CompanyMaster 
            where Companyid >= (SELECT MAX(Companyid) - 1 FROM tbl_CompanyMaster)
            

            【讨论】:

              【解决方案11】:

              因此,本着只使用 OP 中所述的一个 SELECT 子句并彻底滥用 T-SQL 的精神,我提供了一些我永远不会推荐在生产中使用但仍满足规定标准的东西:

              update Cinema
              set Cinema.SomeField = Cinema.SomeField
              output inserted.*
              from Cinema
              inner join 
              (
                  select top 2 CinemaID, ROW_NUMBER() over (order by CinemaID desc) as RowNum
                  from Cinema
              ) rsRowNum on rsRowNum.CinemaID = Cinema.CinemaID
              where RowNum = 2
              

              【讨论】:

                【解决方案12】:

                两个选择,但有点快

                select top 1 * from(
                SELECT TOP 2 * From Cinema 
                WHERE CinemaID
                ORDER BY CinemaID DESC) top2
                Order by CinemaID
                

                【讨论】:

                • 我猜第二个DESC 应该是ASC
                • 是的,复制和粘贴有点疯狂。
                【解决方案13】:

                在一次选择中获取倒数第二行:

                SELECT TOP 1 * From
                (select Top 2 * from Cinema ORDER BY CinemaID DESC) x                     
                ORDER BY CinemaID
                

                实际上只有“一个”选择,因为外部选择仅超过 2 行。

                【讨论】:

                • 如果表格只有一行,这可能会返回不正确的结果。
                【解决方案14】:

                做到这一点(并且与 ANSI SQL 标准兼容)的最佳方法是使用带有 ROW_NUMBER 函数的 CTE(通用表表达式):

                ;WITH OrderedCinemas AS
                (
                   SELECT 
                       CinemaID, CinemaName, 
                       ROW_NUMBER() OVER(ORDER BY CinemaID DESC) AS 'RowNum'
                   FROM dbo.Cinema
                )
                SELECT 
                   CinemaID, CinemaName
                FROM OrderedCinemas
                WHERE RowNum = 2
                

                通过使用这种结构,您可以很容易地获得第二高的值 - 或第五高的值 (WHERE RowNum = 5) 或前 3 行 (WHERE RowNum &lt;= 3) 或任何您需要的值 - CinemaID 值只是有序的并按顺序编号供您使用。

                【讨论】:

                  【解决方案15】:

                  以下不起作用,解释原因: Using ranking-function derived column in where clause (SQL Server 2008)

                  为了完整起见,我会保留在这里:


                  SELECT row_number() OVER (ORDER BY col) r, *
                  FROM tbl
                  WHERE r = 2
                  

                  更多信息: http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile


                  所以我认为最易读的方式是:

                  SELECT * FROM (SELECT row_number() OVER (ORDER BY col) r, * FROM tbl) q
                  WHERE r = 2
                  

                  【讨论】:

                  • 不能在 where 子句中使用 rank()。
                  • 因为窗口函数(如 rank())只允许在 select 或 order by 子句中使用。我试过了><.>
                  • 不起作用的部分恰好是我正在寻找的。 :) 非常感谢您的帮助。
                  【解决方案16】:

                  您只使用了一个 SELECT 语句。 SELECT 语句可以包含任意(或多或少)数量的子查询——相关子查询、标量子查询等,每个子查询都有自己的 SELECT 子句。但它仍然只是一个 SELECT 语句。

                  如果您想避免子查询,您可以选择前 2 个,然后跳过您不想要的那个。不过,这种编程非常脆弱。您必须记住每次要跳过的内容;迟早你会忘记的。

                  【讨论】:

                  • “SELECT 语句”真的是一个技术术语吗?我认为正常的术语是“查询”。无论如何,OP 没有说“只有一个 SELECT 语句”,而是“只有一个选择”。这很容易意味着“只有一个 SELECT 子句”。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-04-01
                  • 1970-01-01
                  • 2014-12-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多