【问题标题】:Order by desc as default option for SQL Server Management Studio?按 desc 排序作为 SQL Server Management Studio 的默认选项?
【发布时间】:2012-02-09 19:05:20
【问题描述】:

有没有办法让 SQL Server Management Studio 默认返回行降序? 每次我通过菜单打开一个表(例如通过选择返回所有行),我都会在顶部获得最旧的行。 我知道我可以在 sql 语句中添加 'order by desc',但是打字很烦人 :)

【问题讨论】:

    标签: sql-server sql-order-by ssms


    【解决方案1】:

    SQL 中没有默认的排序顺序

    如果您在顶部看到“最旧”,那么这可能是引擎检索它的最快方式,因为它是存储在磁盘上的方式。

    你不能保证按这个顺序得到它,除非你指定一个顺序,否则认为它是“无序的”!

    ORDER BY 是按特定顺序获得结果的唯一方法。

    根据指定的表和顺序,排序可能是一项昂贵的操作,因此无序是常态。

    【讨论】:

    • 我明白你在说什么,但我只是想知道 SQL Server Management Studio 中是否有一些设置。当您右键单击表格时,您可以选择检索“top (x)”,我希望有一些设置“order desc”
    • @MartindeWildt TOP X 只是为了限制结果集。您当然可以添加ORDER BY。在正常情况下,如果没有连接,返回的结果很可能是聚集索引键顺序。
    • 我认为这个问题的一个更好的标题可能是“有没有办法更改 SQL Server Management Studio 中的默认 SELECT 查询”?
    • 还有一个更好的标题是“有没有办法在 SQL Server Management Studio 中更改每个表的默认 SELECT 查询?”您会发现大多数解决方法都在 SSMS 安装级别,而不是特定于每个表,由于列差异,这是必要的。
    【解决方案2】:

    JNK 所说的 100% 正确。

    但是,如果您只是希望它正常工作,并且在您打开表格而不是当你查询一个表时...

    尝试添加聚集索引,第一个索引字段按降序索引。这可能实际上会导致您需要的结果。

    (如果您在该字段上已有聚集索引,请编辑其属性并更改其顺序。)


    如果这样的索引对表的实际使用友好,这只是一个明智的想法。仅仅为了您的方便,拥有一个以编程方式无用的索引将是自我挫败;)

    【讨论】:

    • +1 为他可能想要的东西提供了一个解决方法(而不是像我一样只是告诉他他错了:))
    • 如果它们聚集在同一列上,插入性能会不会很糟糕?
    • @SpectralGhost 是的,我认为这可能会导致逻辑碎片问题。分配的新扩展区可能在文件中较晚的页码处,而逻辑上它们需要在文件中较早的位置。
    • 这个想法不是改变数据库中的值,只是它们在查看它们时呈现给我的方式就像我可以从我希望的上下文菜单中获得'top(x)'我可以以某种方式获得“按 id desc 排序”:)
    • 是的 definitely not good for fragmentation 假设它们按升序插入。
    【解决方案3】:

    引自 Itzik Ben-Gan 的 Microsoft SQL Server 2012 T-SQL Fundamentals -> 第 1 章 -> 理论背景 -> 集合论:

    ...当您针对数据库中的表(例如员工表)编写 T-SQL 查询时,您应该将员工集视为一个整体,而不是单个员工。 ... 换句话说,对表的查询可以按任何顺序返回表行,除非您明确要求以特定方式对数据进行排序,可能是出于演示目的。

    SSMS 不支持自定义的默认 SELECT 语句。如果确实支持,应该在 ORDER BY 子句之后放置哪一列,考虑表

    1. 没有像“CreatedDate”这样的列;
    2. 或主键为 GUID(顺序不明显)
    3. 或者没有主键或聚集索引

    即使 SQL SERVER 有一天也能列出最新的数据,这不是根据表考虑单个行(最新/最旧)的自然方式。尝试使用 UPDATE 语句结合 ORDER BY 子句来更新最新数据。

    【讨论】:

      【解决方案4】:

      您不能更改现有模板以从 SSMS 的上下文菜单中生成 SELECT。

      谢天谢地,SSMS 是可扩展的。这意味着您可以编写自己的扩展来完全满足您的需求,或者您可以使用一些现有的解决方案。我会推荐 Mladen 的 SSMS 工具包:

      http://www.ssmstoolspack.com/

      直到最近它还是免费的,并且仍然适用于 2008r2 及更早的版本。

      【讨论】:

        【解决方案5】:

        查看 Profiler 的输出,查询似乎是动态生成的,所以我不会把希望寄托在可以在某处更改的模板上

        /****** Script for SelectTopNRows command from SSMS  ******/
        SELECT TOP 1000 [field1]
              ,[field2]
              ,[field3]
              ,[last_modified]
          FROM [test_database].[dbo].[t_test]
        

        作为替代方案,您可以创建一个小型存储过程,该过程采用表名,然后从所述表中返回数据。假设您的表中有(重复出现的)逻辑可以指示记录的“年龄”,那么找出所述表的默认顺序应该不会太难。如果然后将此存储过程链接到热键,您可以轻松地按照您想要的顺序从所述表中获取前 n 条记录。我知道这与在对象资源管理器中获取信息并不完全相同,但我个人从不使用对象资源管理器,而是喜欢通过简单地在查询窗口中选择文本并按 CTRL-3 来获取表格的内容。

        为了让你开始,它看起来像这样

        IF OBJECT_ID('p_select_top_100_desc') IS NOT NULL DROP PROCEDURE p_select_top_100_desc 
        GO
        CREATE PROCEDURE p_select_top_100_desc ( @table_name sysname)
        AS
        
        DECLARE @object_id int
        DECLARE @order_by_col nvarchar(max)
        DECLARE @sql nvarchar(max)
        
        SELECT @object_id = Object_id(@table_name),
               @order_by_col = ''
        
        IF @object_id IS NULL
            BEGIN
                RaisError('Could not find table %s ?!', 16, 1, @table_name)
                Return(-1)
            END
        
        -- find order by column
        SELECT TOP 1 @order_by_col = c.name
          FROM sys.columns c
         WHERE c.object_id = @object_id
           AND lower(c.name) in ('modified', 'last_modified', 'change_date', 'crdate', 'etc')
        
        -- if none found, use the identity column
        SELECT @order_by_col = c.name + ' DESC'
          FROM sys.columns c
         WHERE c.object_id = @object_id
           AND c.is_identity = 1
           AND @order_by_col  = ''
        
        -- if still none found, use the PK (reverse order)        
        SELECT @order_by_col = @order_by_col
                + (CASE WHEN ic.index_column_id = 1 THEN '' ELSE ',' END)
                + c.name 
                + (CASE WHEN ic.is_descending_key = 0 THEN ' DESC' ELSE ' ASC' END)
          FROM sys.indexes i 
          JOIN sys.index_columns ic
            ON ic.object_id = i.object_id
           AND ic.index_id  = i.index_id
          JOIN sys.columns c
            ON c.object_id  = ic.object_id
           AND c.column_id  = ic.column_id
         WHERE i.object_id  = @object_id
           AND i.is_primary_key = 1
           AND @order_by_col  = ''
         ORDER BY ic.index_column_id
        
        -- actual query
        SELECT @sql = 'SELECT TOP 100 * FROM ' 
                    + @table_name
                    + (CASE WHEN @order_by_col = '' THEN '' ELSE ' ORDER BY ' + @order_by_col END)
        
        PRINT @sql
        EXEC (@sql)
        
        Return 0
        
        GO
        
        EXEC p_select_top_100_desc 't_test'
        

        要将其“链接”到热键,您需要转到Tools \ Customize 菜单,单击[Keyboard...] 按钮。展开树中的 Keyboard 分支并转到 Query Shortcuts 叶。然后,您会得到一个烦人的网格,它允许您将存储过程链接到 CTRL-nbr 组合。请注意,其中一些是固定的 + 在您配置它并按 OK 后,该设置仅适用于您新打开的查询窗口,现有的将适用于“旧”配置。

        希望对你有所帮助……

        PS:如果你将它命名为sp_select_top_n_desc 并在主数据库中编译它,你应该能够在整个服务器上使用它,而无需在每个数据库中部署它。但是,您可能需要切换到dynamic-sql,然后在所有sys.table 查询前加上DB_Name() 的输出,否则它可能会在master.sys.columns 表等中查找。这不是你的想要=)

        【讨论】:

          【解决方案6】:

          尝试像这样在该表上创建一个视图,并在您的选择子句或即席查询中使用它

          CREATE VIEW dbo.yourTable_vw
          AS 
              SELECT TOP 100 PERCENT *
              FROM yourTable
              ORDER BY yourcolumn DESC
          GO
          

          【讨论】:

            【解决方案7】:

            实际上,您可以为 ssms 创建一个插件,将新项目添加到对象浏览器的上下文菜单中。

            检查这个问题:Create custom menu item in Object Explorer

            另一种方法是创建一个 SP,它在主数据库中(在所有服务器上)使用 ORDER BY 子句生成并执行 select 语句,并将键盘快捷键绑定到该 sp。

            【讨论】:

              【解决方案8】:

              虽然官方没有简单线性输入的默认排序顺序,但我使用 PK 或 IX 排序顺序获得了令人满意的 DESC 默认排序顺序。假设我对最后一个条目最感兴趣的日志表。

              CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
              CONSTRAINT [PK_tableA] 
              PRIMARY KEY CLUSTERED ([DateTime] DESC)
              WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
              ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
              

              或者在 SSMS 中 ...

              【讨论】:

                【解决方案9】:

                对我来说 - 我首先使用 EF 代码,但每当我创建一个新表时都会这样做: 右键单击表,将表编写为 -> 删除和创建表,然后编辑 SQL 并将键更改为 DESC,然后运行脚本.. 完成(没有视图或任何混乱)

                【讨论】:

                  【解决方案10】:
                  create table MYTESTTABLE (
                      ID numeric(18, 0) identity(1, 1) not null
                      ,COL1 numeric(18, 0) null
                      ,COL2 numeric(18, 0) null
                      ,COL3 numeric(18, 0) null
                      ,COL4 numeric(18, 0) null
                   CONSTRAINT [PK_MYTESTTABLE] PRIMARY KEY CLUSTERED 
                  (
                      [ID] DESC
                  )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
                  ) ON [PRIMARY]
                  GO
                  
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-03-05
                    • 2018-12-31
                    • 2015-10-06
                    • 1970-01-01
                    • 2011-06-18
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多