标签: t-sql

TSQL 性能 - 加入最小值和最大值之间的值

我有两张表用于存储:

  • IP 范围 - 国家/地区查找表
  • 来自不同 IP 的请求列表

IP 存储为bigints 以提高查找性能。

这是表结构:

create table [dbo].[ip2country](
    [begin_ip] [varchar](15) NOT NULL,
    [end_ip] [varchar](15) NOT NULL,
    [begin_num] [bigint] NOT NULL,
    [end_num] [bigint] NOT NULL,
    [IDCountry] [int] NULL,
    constraint [PK_ip2country] PRIMARY KEY CLUSTERED 
    (
        [begin_num] ASC,
        [end_num] ASC
    )
)

create table Request(
    Id int identity primary key, 
    [Date] datetime, 
    IP bigint, 
    CategoryId int
)
Run Code Online (Sandbox Code Playgroud)

我想获取每个国家/地区的请求细分,因此我执行以下查询:

select 
    ic.IDCountry,
    count(r.Id) as CountryCount
from Request r
left join ip2country ic 
  on r.IP between ic.begin_num …
Run Code Online (Sandbox Code Playgroud)

performance sql-server-2008 t-sql query-performance

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

T SQL 表值函数以逗号分隔列

我在 Microsoft SQL Server 2008 中编写了一个表值函数,以在数据库中使用逗号分隔的列来为每个值吐出单独的行。

例如:“一、二、三、四”将返回一个只有一列包含以下值的新表:

one
two
three
four
Run Code Online (Sandbox Code Playgroud)

这段代码看起来容易出错吗?当我测试它时

SELECT * FROM utvf_Split('one,two,three,four',',') 
Run Code Online (Sandbox Code Playgroud)

它永远运行并且永远不会返回任何东西。这真的很令人沮丧,尤其是因为 MSSQL 服务器上没有内置的拆分函数(为什么为什么为什么?!)而且我在网上找到的所有类似函数都是绝对垃圾或根本与我想要做的事情无关.

这是函数:

USE *myDBname*
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[utvf_SPlit] (@String VARCHAR(MAX), @delimiter CHAR)

RETURNS @SplitValues TABLE
(
    Asset_ID VARCHAR(MAX) NOT NULL
)

AS
BEGIN
            DECLARE @FoundIndex INT
            DECLARE @ReturnValue VARCHAR(MAX)

            SET @FoundIndex = CHARINDEX(@delimiter, @String)

            WHILE (@FoundIndex <> 0)
            BEGIN
                  DECLARE @NextFoundIndex INT
                  SET @NextFoundIndex = CHARINDEX(@delimiter, @String, @FoundIndex+1)
                  SET @ReturnValue = SUBSTRING(@String, @FoundIndex,@NextFoundIndex-@FoundIndex)
                  SET …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server t-sql functions

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

如何展平具有两个相关“许多”表的表的结果?

我重新组织了数据库中的一些表以使其更加灵活,但我不确定如何编写 SQL 以从中提取有意义的数据。

我有以下表格(为了更清楚的例子,有些缩写):

CREATE TABLE Loans(
    Id int,
    SchemaId int,
    LoanNumber nvarchar(100)
);

CREATE TABLE SchemaFields(
    Id int,
    SchemaId int,
    FieldName nvarchar(255)
);

CREATE TABLE LoanFields(
    Id int,
    LoanId int,
    SchemaFieldId int,
    FieldValue nvarchar(4000)
);
Run Code Online (Sandbox Code Playgroud)

使用以下数据:

INSERT INTO Loans (Id, SchemaId, LoanNumber) VALUES (1, 1, 'ABC123');

INSERT INTO SchemaFields (Id, SchemaId, FieldName) VALUES (1, 1, 'First Name');
INSERT INTO SchemaFields (Id, SchemaId, FieldName) VALUES (2, 1, 'Last Name');

INSERT INTO LoanFields (Id, LoanId, SchemaFieldId, FieldValue) VALUES (1, 1, 1, …
Run Code Online (Sandbox Code Playgroud)

pivot t-sql sql-server-2012

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

如何在 SQL Server 中进行比较时包含空值?

所以基本上在 SQL Server 中,NULL 意味着没有值,因此无法比较它返回一些意外的结果。

例如,以下查询不会返回值为 NULL 的行,但我希望它返回:

SELECT *
FROM table
WHERE
  (value != 26)
  AND date IS NULL
  AND last_modified >= '5/21/2014'
Run Code Online (Sandbox Code Playgroud)

我知道我可以做以下作为一种解决方法,但认真吗?每次我想包含它时,都必须添加括号并检查每个字段是否为空?看起来丑陋,不直观和疯狂。

SELECT *
FROM table
WHERE
  (value != 26 OR value is null)
  AND date IS NULL
  AND last_modified >= '5/21/2014'
Run Code Online (Sandbox Code Playgroud)

我的意思是我知道 NULL 不是一个值,因此无法进行比较,但您不能推断它实际上绝对不是 26 吗?如果 26 是什么,NULL 是什么,什么都不是什么,那么 NULL 不是 26。对我来说似乎是合乎逻辑的。

有谁知道我如何以更简洁的方式在使用比较时在结果中包含空值,而不必每次都包含显式检查。同样关闭我的表上的空值绝对不是一种选择。

编辑:

我为什么不想像我展示的那样做的真正问题并没有暴露出来。所以就到这里了。我正在编写一个程序,让您构建对数据库表的查询,让用户动态创建过滤器等,基本上在一天结束时构建 SQL 语句并将结果显示给用户。用户选择的字段可以是给定数据库中的任何和/或所有字段,如果我必须逐字地将 ISNULL 检查放在每个字段上,这将非常低效,并使查看 SQL 变得非常难看。我的程序与表定义无关,这意味着我不在乎你的表中有什么,也不想知道你的表的定义是什么。我只是想让你选择一个表格,选择一些字段来过滤等于、不等于、在、不在等......

null sql-server t-sql

10
推荐指数
2
解决办法
5万
查看次数

连接多个表会导致重复的行

我得到的行比我期望的查询返回的行多。

我相信这与我的 join 语句有关。

有多个表,其中包含不同的信息。 Person保存有关此人的主要信息,但不保存地址、电话或电子邮件。这是因为最初的设计师希望桌子能够容纳多个电话号码、电子邮件和地址。

SELECT (person.FirstName + ' ' + person.LastName) as FullName
    ,ISNULL(Person.isClient, '')
    ,ISNULL(Person.UDF1, '')
    ,ISNULL(Address.City, '')
    ,ISNULL(Address.state, '')
    ,PersonAddress.Person
    ,PersonAddress.Address
    ,ISNULL(Phone.PhoneNumber, 'N/A')
    ,Email.Email
    ,Person.Website
FROM Person
    left join PersonAddress on Person.ID = PersonAddress.Person
    left join Address on PersonAddress.Address = Address.ID
    left join PersonPhone on Person.ID = PersonPhone.Person
    left join Phone on PersonPhone.Person = Phone.ID
    left join Email with (nolock) on Person.ID = Email.Person
WHERE (
        isclient = 'prospect'
        or isclient = 'client'
        )
    and …
Run Code Online (Sandbox Code Playgroud)

sql-server-2005 join sql-server t-sql

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

使用 FOREIGN KEY 上的显式单个 KEY 值克服 MERGE JOIN(INDEX SCAN)

添加 7/11问题是由于 MERGE JOIN 期间的索引扫描而发生死锁。在这种情况下,一个事务试图在 FK 父表的整个索引上获得 S 锁,但之前另一个事务在索引的键值上放置了 X 锁。

让我从一个小例子开始(使用来自 70-461 课程的 TSQL2012 DB):

CREATE TABLE [Sales].[Orders](
[orderid] [int] IDENTITY(1,1) NOT NULL,
[custid] [int] NULL,
[empid] [int] NOT NULL,
[shipperid] [int] NOT NULL,
... )
Run Code Online (Sandbox Code Playgroud)

[custid], [empid], [shipperid]是相应的相关参数[Sales].[Customers], [HR].[Employees], [Sales].[Shippers]。在每种情况下,我们在父表中的引用列上都有一个聚集索引。

ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Customers] FOREIGN KEY([custid]) REFERENCES [Sales].[Customers] ([custid])
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Employees] FOREIGN KEY([empid]) REFERENCES [HR].[Employees] ([empid])
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT …
Run Code Online (Sandbox Code Playgroud)

performance foreign-key deadlock optimization t-sql query-performance

10
推荐指数
1
解决办法
728
查看次数

sql server:以小块更新大表上的字段:如何获取进度/状态?

我们有一个非常大(1 亿行)的表,我们需要更新其中的几个字段。

对于日志运输等,我们显然也希望将其保持为一口大小的交易。

  • 下面会做的伎俩吗?
  • 我们如何让它打印一些输出,以便我们可以看到进度?(我们尝试在其中添加 PRINT 语句,但在 while 循环期间没有输出任何内容)

代码是:

DECLARE @CHUNK_SIZE int
SET @CHUNK_SIZE = 10000

UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
where deleted is null or deletedDate is null

WHILE @@ROWCOUNT > 0
BEGIN
    UPDATE TOP(@CHUNK_SIZE) [huge-table] set deleted = 0, deletedDate = '2000-01-01'
    where deleted is null or deletedDate is null
END
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

10
推荐指数
1
解决办法
9827
查看次数

过滤索引仅在过滤部分在 JOIN 而不是 WHERE 时使用

我已经在下面创建了过滤索引,但是当我进一步运行 2 个查询时,该索引仅用于第一个示例中的查找,该示例在 JOIN 中有 END_DTTM 而不是 where 子句(这是查询中的唯一区别) . 任何人都可以解释为什么会发生这种情况?

索引创建

CREATE NONCLUSTERED INDEX [ix_PATIENT_LIST_BESPOKE_LIST_ID_includes] ON [dbo].[PATIENT_LIST_BESPOKE] 
(
    [LIST_ID] ASC,
    [END_DTTM] ASC
)
WHERE ([END_DTTM] IS NULL)
Run Code Online (Sandbox Code Playgroud)

查询

DECLARE @LIST_ID INT = 3655

--This one seeks on the index

SELECT  
    PATIENT_LISTS.LIST_ID
FROM    
    DBO.PATIENT_LISTS
    LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID  
                                      AND PATIENT_LIST_BESPOKE.END_DTTM IS NULL
WHERE
    PATIENT_LISTS.LIST_ID = @LIST_ID

--This one scans on the index

SELECT  
    PATIENT_LISTS.LIST_ID
FROM    
    DBO.PATIENT_LISTS
    LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID  
WHERE   
    PATIENT_LISTS.LIST_ID = @LIST_ID …
Run Code Online (Sandbox Code Playgroud)

performance index sql-server t-sql filtered-index query-performance

10
推荐指数
2
解决办法
2759
查看次数

FIRST() 和 LAST() 的 SQL Server 2012 版本是什么?

我有一个带value列的表。我想计算最后一行减去第一行,如下所示:

 id      value
  1       10
  2       45
  3       65
  4       95
  .       .
  .       .
  .       .
 500     200
Run Code Online (Sandbox Code Playgroud)

我想获得 200 - 10 = 190

我试着然而,在SQL Server 2012中使用下面的命令,LAST并且FIRST不工作。

SELECT LAST(Value) - FIRST(Value) FROM Counter;
Run Code Online (Sandbox Code Playgroud)

SQL Server 中此命令的语法是什么?

sql-server t-sql sql-server-2012

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

用空格替换列中的特殊字符

我正在尝试编写一个用空格替换特殊字符的查询。下面的代码有助于识别行。(字母数字字符、逗号和空格有效):

SELECT columnA
FROM tableA
WHERE columnA like '%[^a-Z0-9, ]%'
Run Code Online (Sandbox Code Playgroud)

如何将替换函数集成到 select 语句中,以便结果集中除字母数字、逗号和空格之外的所有字符都替换为 ' '(空格)。这个不行:

SELECT replace(columnA,'%[^a-Z0-9, ]%',' ')
FROM tableA
WHERE columnA like '%[^a-Z0-9, ]%'
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2008-r2 replace

10
推荐指数
2
解决办法
11万
查看次数