标签: sql-server

将结果限制在前 2 个排名行

在SQL Server 2008中,我使用RANK() OVER (PARTITION BY Col2 ORDER BY Col3 DESC)与返回的数据集RANK。但是我每个分区有数百条记录,所以我将从等级 1、2、3......999 中获取值。但我只想RANKs在每个PARTITION.

例子:

ID   Name    Score    Subject
1    Joe      100      Math
2    Jim      99       Math
3    Tim      98       Math
4    Joe      99       History
5    Jim      100      History
6    Tim      89       History
7    Joe      80       Geography
8    Tim      100      Geography
9    Jim      99       Geography
Run Code Online (Sandbox Code Playgroud)

我希望结果是:

SELECT Subject, Name, RANK() OVER (PARTITION BY Subject ORDER BY Score DESC)
FROM Table
Run Code Online (Sandbox Code Playgroud)
Subject        Name      Rank …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server t-sql window-functions rank

24
推荐指数
2
解决办法
6万
查看次数

如何与特权孩子建立一对多关系?

我想要一种一对多的关系,其中对于每个父母,一个或零个孩子被标记为“最喜欢的”。然而,并不是每个父母都会有孩子。(将家长视为本网站上的问题,将孩子视为答案,将最喜欢的视为已接受的答案。)例如,

TableA
    Id            INT PRIMARY KEY

TableB
    Id            INT PRIMARY KEY
    Parent        INT NOT NULL FOREIGN KEY REFERENCES TableA.Id
Run Code Online (Sandbox Code Playgroud)

在我看来,我可以将以下列添加到 TableA:

    FavoriteChild INT NULL FOREIGN KEY REFERENCES TableB.Id
Run Code Online (Sandbox Code Playgroud)

或 TableB 的以下列:

    IsFavorite    BIT NOT NULL
Run Code Online (Sandbox Code Playgroud)

第一种方法的问题在于它引入了一个可为空的外键,据我所知,它不是规范化形式。第二种方法的问题是需要做更多的工作来确保最多只有一个孩子是最喜欢的。

我应该使用什么样的标准来确定使用哪种方法?或者,还有其他我没有考虑的方法吗?

我正在使用 SQL Server 2012。

normalization foreign-key database-design sql-server relational-theory

24
推荐指数
2
解决办法
1万
查看次数

SQL Server 的 READ COMMITTED SNAPSHOT 与 SNAPSHOT

我正在研究 SQL ServerREAD COMMITTED SNAPSHOT和SNAPSHOT隔离级别之间的差异,并发现以下资源:

选择基于行版本控制的隔离级别

对于大多数应用程序,由于以下原因,建议使用行版本控制读取提交隔离而不是快照隔离:

  • 与快照隔离相比,它消耗的 tempdb 空间更少。

  • 快照隔离容易受到更新冲突的影响,这些冲突不适用于使用行版本控制的已提交读隔离。当一个在快照隔离下运行的事务读取数据然后被另一个事务修改时,快照事务对相同数据的更新会导致更新冲突,事务终止并回滚。这不是使用行版本控制的已提交读隔离的问题。

我对这些主题有些陌生,但我似乎无法理解上面链接中的两个要点。

  1. 为什么这些模式的 tempdb 空间会不同?一个存储比另一个更精细的版本控制吗?

  2. 为什么快照隔离更容易受到更新冲突的影响?

sql-server sql-server-2012

24
推荐指数
1
解决办法
1万
查看次数

SQL Server 2012:从命令行生成脚本

我正在运行 SQL Server 2012。

SQL Server Management Studio 可以选择右键单击数据库,然后选择任务和生成脚本。

有没有办法通过命令行以某种方式自动化?

我想创建一个包含整个数据库的架构和数据的脚本。

之类的工具ScriptDB,并sqlpubwiz.exe似乎都针对SQL Server 2005的什么有关SQL Server 2012?

sql-server scripting

24
推荐指数
4
解决办法
4万
查看次数

使用 T-SQL 测试字符串是否为回文

我是 T-SQL 的初学者。我想确定输入字符串是否是回文,如果不是,则输出 = 0,如果是,则输出 = 1。我仍在弄清楚语法。我什至没有收到错误消息。我正在寻找不同的解决方案和一些反馈,以更好地理解和了解 T-SQL 的工作原理,从而变得更好——我仍然是一名学生。

在我看来,关键思想是将最左边和最右边的字符相互比较,检查是否相等,然后继续比较左边第二个字符和倒数第二个字符,依此类推。我们做一个循环:如果字符彼此相等,我们继续。如果到达终点,则输出 1,否则,输出 0。

请您批评一下:

CREATE function Palindrome(
    @String  Char
    , @StringLength  Int
    , @n Int
    , @Palindrome BIN
    , @StringLeftLength  Int
)
RETURNS Binary
AS
BEGIN
SET @ n=1
SET @StringLength= Len(String)

  WHILE @StringLength - @n >1

  IF
  Left(String,@n)=Right(String, @StringLength)

 SET @n =n+1
 SET @StringLength =StringLength -1

 RETURN @Binary =1

 ELSE RETURN @Palindrome =0

END
Run Code Online (Sandbox Code Playgroud)

我认为我在正确的轨道上,但我还有很长的路要走。有任何想法吗?

sql-server t-sql sql-server-2012 functions

24
推荐指数
8
解决办法
7790
查看次数

归档除当前年份以外的所有数据并同时对表进行分区的最佳方法是什么

任务

从一组大表中归档除滚动 13 个月之外的所有内容。存档数据必须存储在另一个数据库中。

  • 数据库处于简单恢复模式
  • 这些表从 5000 万行到几十亿行,在某些情况下每个表占用数百 GB。
  • 表当前未分区
  • 每个表在不断增加的日期列上都有一个聚集索引
  • 每个表额外有一个非聚集索引
  • 对表的所有数据更改都是插入
  • 目标是最大限度地减少主数据库的停机时间。
  • 服务器是 2008 R2 Enterprise

“归档”表将有大约 11 亿行,“活”表大约有 4 亿行。显然存档表会随着时间的推移而增加,但我希望活动表也能合理快速地增加。至少在接下来的几年里说 50%。

我曾考虑过 Azure 扩展数据库,但不幸的是我们在 2008 R2 并且可能会在那里停留一段时间。

当前计划

  • 创建一个新的数据库
  • 在新数据库中创建按月(使用修改日期)分区的新表。
  • 将最近 12-13 个月的数据移动到分区表中。
  • 对两个数据库进行重命名交换
  • 从现在的“归档”数据库中删除移动的数据。
  • 对“归档”数据库中的每个表进行分区。
  • 将来使用分区交换来归档数据。
    • 我确实意识到我必须换出要存档的数据,将该表复制到存档数据库,然后将其交换到存档表中。这是可以接受的。

问题: 我正在尝试将数据移动到初始分区表中(实际上我仍在对其进行概念验证)。我正在尝试使用 TF 610(根据数据加载性能指南)和一个INSERT...SELECT语句来移动数据,最初认为它会被最少记录。不幸的是,每次我尝试它都被完全记录。

在这一点上,我认为我最好的选择可能是使用 SSIS 包移动数据。我试图避免这种情况,因为我正在处理 200 个表,并且我可以通过脚本轻松生成和运行任何我可以做的事情。

我的总体计划中是否遗漏了任何内容,SSIS 是快速移动数据和最少使用日志(空间问题)的最佳选择吗?

没有数据的演示代码

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] …
Run Code Online (Sandbox Code Playgroud)

sql-server architecture sql-server-2008-r2 archive

24
推荐指数
1
解决办法
7949
查看次数

为什么这个 MERGE 语句会导致会话被终止?

我有以下MERGE针对数据库发出的语句:

MERGE "MySchema"."Point" AS t
USING (
       SELECT "ObjectId", "PointName", z."Id" AS "LocationId", i."Id" AS "Region"
         FROM @p1 AS d
         JOIN "MySchema"."Region" AS i ON i."Name" = d."Region"
    LEFT JOIN "MySchema"."Location" AS z ON z."Name" = d."Location" AND z."Region" = i."Id"
       ) AS s
   ON s."ObjectId" = t."ObjectId"
 WHEN NOT MATCHED BY TARGET 
    THEN INSERT ("ObjectId", "Name", "LocationId", "Region") VALUES (s."ObjectId", s."PointName", s."LocationId", s."Region")
 WHEN MATCHED 
    THEN UPDATE 
     SET "Name" = s."PointName"
       , "LocationId" = s."LocationId"
       , "Region" …
Run Code Online (Sandbox Code Playgroud)

sql-server merge sql-server-2014 sql-server-2016

24
推荐指数
1
解决办法
975
查看次数

如何将表中的最大行数限制为 1

我的 SQL Server 数据库中有一个配置表,该表应该只有一行。为了帮助未来的开发人员理解这一点,我想防止添加多于一行的数据。我选择为此使用触发器,如下所示......

ALTER TRIGGER OnlyOneConfigRow
    ON [dbo].[Configuration]
    INSTEAD OF INSERT
AS
BEGIN
    DECLARE @HasZeroRows BIT;
    SELECT  @HasZeroRows = CASE
        WHEN COUNT (Id) = 0 THEN 1
        ELSE 0
    END
    FROM
        [dbo].[Configuration];

    IF EXISTS(SELECT [Id] FROM inserted) AND @HasZeroRows = 0
    BEGIN
        RAISERROR ('You should not add more than one row into the config table. ', 16, 1)    
    END
END
Run Code Online (Sandbox Code Playgroud)

这不会引发错误,但不允许第一行进入。

还有比这更有效/更自我解释的方法可以将可以插入表中的行数限制为 1 吗?我是否缺少任何内置的 SQL Server 功能?

trigger sql-server insert limits row

24
推荐指数
3
解决办法
3万
查看次数

从 DMV 中,您能否判断连接是否使用 ApplicationIntent=ReadOnly?

我设置了一个 Always On Availability Group,我想确保我的用户在他们的连接字符串中使用 ApplicationIntent=ReadOnly。

从 SQL Server 通过 DMV(或扩展事件或其他),我能否判断用户是否在其连接字符串中使用 ApplicationIntent=ReadOnly 进行连接?

请不要回答如何防止连接 - 这不是这个问题的内容。我不能简单地停止连接,因为我们现有的应用程序在没有正确字符串的情况下进行连接,我需要知道它们是哪些,以便我可以与开发人员和用户合作,随着时间的推移逐渐修复它。

假设用户有多个应用程序。例如,Bob 与 SQL Server Management Studio 和 Excel 连接。他需要更新时使用 SSMS,需要读取时使用 Excel。我需要确保他在与 Excel 连接时使用 ApplicationIntent=ReadOnly。(这不是确切的场景,但足以说明。)

sql-server availability-groups

24
推荐指数
3
解决办法
2977
查看次数

LIKE 运算符的基数估计(局部变量)

我的印象是,当LIKE在所有针对未知场景的优化中使用运算符时,旧版和新版 CE 都使用 9% 的估计值(假设相关统计数据可用并且查询优化器不必求助于选择性猜测)。

当对信用数据库执行以下查询时,我在不同的 CE 下得到不同的估计。在新的 CE 下,我收到了我期望的 900 行的估计值,在旧版 CE 下,我收到了 241.416 的估计值,但我无法弄清楚这个估计值是如何得出的。有没有人能够发光?

-- New CE (Estimate = 900)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName;

-- Forcing Legacy CE (Estimate = 241.416)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName
OPTION (
QUERYTRACEON 9481,
QUERYTRACEON 9292,
QUERYTRACEON 9204,
QUERYTRACEON 3604
);
Run Code Online (Sandbox Code Playgroud)

在我的场景中,我已经将信用数据库设置为兼容性级别 120,因此为什么在第二个查询中我使用跟踪标志来强制使用旧版 CE 并提供有关查询优化器使用/考虑的统计信息的信息。我可以看到正在使用有关“姓氏”的列统计信息,但我仍然无法弄清楚 241.416 的估计值是如何得出的。

除了这篇 Itzik Ben-Gan 文章之外,我在网上找不到任何其他 …

sql-server optimization statistics sql-server-2014 cardinality-estimates

24
推荐指数
2
解决办法
2258
查看次数