标签: t-sql

使用 COALESCE(...) 优化子查询的选择

我有一个从应用程序中使用的大视图。我想我已经缩小了我的性能问题,但我不确定如何解决它。视图的简化版本如下所示:

SELECT ISNULL(SEId + '-' + PEId, '0-0') AS Id,
   *,
   DATEADD(minute, Duration, EventTime) AS EventEndTime
FROM (
    SELECT se.SEId, pe.PEId,
        COALESCE(pe.StaffName, se.StaffName) AS StaffName, -- << Problem!
        COALESCE(pe.EventTime, se.EventTime) AS EventTime,
        COALESCE(pe.EventType, se.EventType) AS EventType,
        COALESCE(pe.Duration, se.Duration) AS Duration,
        COALESCE(pe.Data, se.Data) AS Data,
        COALESCE(pe.Field, se.Field) AS Field,
        pe.ThisThing, se.OtherThing
    FROM PE pe FULL OUTER JOIN SE se 
      ON pe.StaffName = se.StaffName
     AND pe.Duration = se.Duration
     AND pe.EventTime = se.EventTime
    WHERE NOT(pe.ThisThing = 1 AND se.OtherThing = 0)
) Z …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization t-sql subquery

8
推荐指数
1
解决办法
4416
查看次数

SQL Server 如何确定精度/小数位数?

我正在运行 SQL Server 2012

SELECT 
   0.15 * 30 / 360,
   0.15 / 360 * 30 
Run Code Online (Sandbox Code Playgroud)

结果:

 0.012500, 
 0.012480
Run Code Online (Sandbox Code Playgroud)

这个对我来说更令人困惑:

DECLARE @N INT = 360
DECLARE @I DECIMAL(38,26) = 0.15 * 30 / 360     
DECLARE @C DECIMAL(38,26) = 1000000     

SELECT @C *  @I *  POWER(1 + @I, @N)  / ( POWER(1 + @I, @N) - 1 )
SELECT @C * (@I *  POWER(1 + @I, @N)  / ( POWER(1 + @I, @N) - 1 ) )
Run Code Online (Sandbox Code Playgroud)

第一个选择给了我正确的结果:12644.44022 第二个截断结果:12644.00000

sql-server t-sql sql-server-2012 decimal

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

在视图中将列定义为可以为空(但不在引用的表中)

我的公司正在努力实施一个新的 HR 应用程序,以统一我们现有的 HR 流程。不过,我们遇到了一些症结;根据业务规则,Employee表的EmployeeID和SupervisorID列不能为空。但是,应用程序要求这些列可以为空,并且不会在将列设置为不允许为空时同步这些列。

建议的解决方案是创建一个视图,其中架构似乎允许列中存在空值,同时保留表以防止它们被输入到数据中。我并不完全相信这是可能的,而且我一直无法找到一种方法来做到这一点。这可能吗?如果没有,处理这种情况的最佳方法是什么?

sql-server t-sql sql-server-2012

8
推荐指数
1
解决办法
6010
查看次数

查看 XML 元素是否存在于具有特定值的文档中的任何级别

是否可以查询 XML 以查找特定元素是否具有特定值?例如,如果我想查看下面的 XML 在<ContactFName>.

但请注意,元素的位置可能会改变。在某些情况下,它可能在/root/MCTLocations/MCTLocation,或者可能跳到根下,或者出现在其他地方......

并且,是否可以参数化元素名称?

DECLARE @table TABLE (XmlCol XML)

INSERT INTO @table (XmlCol) VALUES ('
<root>
<MCTClientName>John</MCTClientName>
<MCTClientCity>Palm Beach</MCTClientCity>
<MCTLocations>
    <MCTLocation>
        <Address>1234 Main Street</Address>
        <ContactFName>Chris</ContactFName>
        <ContactLName>Brandt</ContactLName>
    </MCTLocation>
</MCTLocations>
</root>')

SELECT * FROM @table WHERE ??
Run Code Online (Sandbox Code Playgroud)

xml sql-server t-sql

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

确定文件夹中多个 .DTSX 包文件的 PackageFormatVersion

Kenneth Fisher 发表了一篇关于如何确定我的 SSIS 包是什么 SQL 版本的博客文章2015 年 4 月。

它有一个表,其中列出了哪些 SQL 版本映射到PackageFormatVersion在 XML 元数据中找到的 SSIS 包。这在查看 1 个单独的包时很有用。

我有一个包含大约 100 个 SSIS.DTSX包的文件夹,我需要知道它们都是哪个 SQL 版本。

如何批量确定文件夹(文件系统)中PackageFormatVersion多个.DTSX包的(即 SQL 版本)是什么?

最终目标是确定哪个是正确的 TFS 版本来获取和实施以将这些包放入,因为当前不存在源代码控制系统。Kenneth 提供的表将帮助我回答这个问题,但首先我需要确认包 SQL 版本是什么。

假设我没有安装 BIDS 或 SSDT。

假设所需的输出是这样的,其中管道指定了一个新列:

PackageFilename | PackageFormatVersion
--------------------------------------
Package1.dtsx   | 3
Package2.dtsx   | 4
Run Code Online (Sandbox Code Playgroud)

欢迎使用 PowerShell、TSQL、可以抓取目录结构的 3rd 方工具或其他工具。

xml sql-server ssis powershell t-sql

8
推荐指数
1
解决办法
1274
查看次数

即使使用非聚集索引和全文索引,SE​​LECT 查询也很慢

我试图从表中查询 0 到 65,000 行。

服务器使用的是Microsoft SQL Server 2014,我无法更改服务器上的硬件。

架构

[Id] (PK)        INT      
[varchar1]  VARCHAR(4)     Normal Cardinality
[varchar2]  VARCHAR(250)   Normal Cardinality
[varchar3]  VARCHAR(250)   Normal Cardinality
[varchar4]  VARCHAR(100)   Normal Cardinality
[date1]     DATETIME       High Cardinality
[varchar5]  VARCHAR(100)   Low Cardinality
[varchar6]  VARCHAR(1000)  Normal Cardinality
[varchar7]  VARCHAR(100)   Normal Cardinality
[varchar8]  VARCHAR(20)    Normal Cardinality
[varchar9]  VARCHAR(100)   High Cardinality
[xml1]      XML            Low Cardinality
Run Code Online (Sandbox Code Playgroud)

询问

以下查询是存储过程的一部分(其余部分无关紧要,因为它对存储过程的性能影响不大)。列名称已替换为列类型和编号:

SELECT   [varchar1]
       , [varchar4]
       , [date1]
       , [varchar5]
       , [varchar6]
       , [varchar7]
       , [varchar8]
       , [varchar9]
       , [xml1]
FROM [database].[dbo].[table] WITH …
Run Code Online (Sandbox Code Playgroud)

sql-server stored-procedures t-sql sql-server-2014

8
推荐指数
1
解决办法
2200
查看次数

SELECT * 在触发器中是否正常。还是我自找麻烦?

我在工作中陷入了争论,我需要一些关于我可能忽略的可能陷阱的建议。

想象一下使用触发器将删除的记录复制到审计表的场景。触发器使用 SELECT *。每个人都指指点点,大喊大叫,告诉我们这有多糟糕。

但是,如果对主表的结构进行了修改,而忽略了审计表,那么触发器将产生一个错误,让人们知道审计表也需要修改。

该错误将在我们的 DEV 服务器上进行测试时被捕获。但是我们需要确保生产与 DEV 匹配,因此我们允许在生产系统中使用 SELECT * (仅限触发器)。

所以我的问题是:我被要求删除 SELECT *,但我不确定如何确保我们自动捕获这种性质的开发错误,任何想法或这是最佳实践?

我在下面整理了一个例子:

--Create Test Table
CREATE TABLE dbo.Test(ID INT IDENTITY(1,1), Person VARCHAR(255))
--Create Test Audit Table
CREATE TABLE dbo.TestAudit(AuditID INT IDENTITY(1,1),ID INT, Person VARCHAR(255))

--Create Trigger on Test
CREATE TRIGGER [dbo].[trTestDelete] ON [dbo].[Test] AFTER DELETE
NOT FOR REPLICATION
AS
BEGIN
    SET NOCOUNT ON;
    INSERT  dbo.TestAudit([ID], [Person])
    SELECT  *
    FROM    deleted
END

--Insert Test Data into Test
INSERT INTO dbo.Test VALUES
('Scooby')
,('Fred')
,('Shaggy')

--Perform a …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

8
推荐指数
2
解决办法
5050
查看次数

给表取别名后对象名无效?

当我运行以下查询时

select distinct A.movieID, A.avgStars from 
(select mID as movieID, avg(stars) as avgStars
from Rating
group by mID) A
where  A.avgStars <= all(select A.avgStars from A);
Run Code Online (Sandbox Code Playgroud)

我收到错误“无效的对象名称‘A’。”

你知道我为什么会得到这个吗?

谢谢!

sql-server t-sql

8
推荐指数
3
解决办法
3387
查看次数

根据特定公式找到最小的缺失元素

我需要能够从具有数千万行的表中找到缺失的元素,并且有一个BINARY(64)列的主键(这是要计算的输入值)。这些值大多按顺序插入,但有时我想重用已删除的先前值。用IsDeleted列修改已删除的记录是不可行的,因为有时插入的行比当前存在的行高数百万个值。这意味着示例数据将类似于:

KeyCol : BINARY(64)
0x..000000000001
0x..000000000002
0x..FFFFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)

因此在0x000000000002和之间插入所有缺失值0xFFFFFFFFFFFF是不可行的,使用的时间和空间量将是不可取的。本质上,当我运行算法时,我希望它返回0x000000000003,这是第一个开口。

我在 C# 中提出了一个二进制搜索算法,它将查询数据库中位置的每个值i,并测试该值是否是预期的。对于上下文,我可怕的算法:https : //codereview.stackexchange.com/questions/174498/binary-search-for-a-missing-or-default-value-by-a-given-formula

例如,该算法将在具有 100,000,000 个项目的表上运行 26-27 个 SQL 查询。(这看起来并不多,但它会非常频繁地发生。)目前,该表中大约有 50,000,000 行,性能变得很明显

我的第一个替代想法是将其转换为存储过程,但这有其自身的障碍。(我必须编写一个BINARY(64) + BINARY(64)算法,以及大量其他东西。)这会很痛苦,但并非不可行。我也考虑过实现基于的翻译算法ROW_NUMBER,但我对此有一种非常糟糕的直觉。(BIGINT对于这些值,A几乎不够大。)

我愿意接受其他建议,因为我真的需要尽快解决这个问题。值得一提的是,C# 查询选择的唯一列是KeyCol,其他列与此部分无关。


此外,对于它的价值,获取适当记录的当前查询是这样的:

SELECT [KeyCol]
  FROM [Table]
  ORDER BY [KeyCol] ASC
  OFFSET <VALUE> ROWS FETCH FIRST 1 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

<VALUE> …

t-sql sql-server-2014 where

8
推荐指数
2
解决办法
470
查看次数

如果存储过程在 TRY / CATCH 中失败,则未设置输出参数

在 SQL Server 2008 中(但也在 2014 年)。让我们考虑一个具有输出参数的过程。此过程可能会产生错误(并且会在以下示例中产生)。我注意到如果我们在TRY/CATCH块中调用过程,输出参数的行为是不一样的。

例子:

create procedure test_output @result varchar(10) output
as
begin
    set @result = 'hello'
    raiserror('This is an error', 16,1)
    set @result = 'error'
end
Run Code Online (Sandbox Code Playgroud)

如果我们以简单的方式启动程序:

declare @res1 varchar(10)
exec test_output @result = @res1 out
print 'Result is: '+ isnull(@res1, 'empty')
Run Code Online (Sandbox Code Playgroud)

我们得到(我很好):

Msg 50000, Level 16, State 1, Procedure test_output, Line 7 [Batch Start Line 12]
这是一个错误
结果是:错误

如果过程现在在 try/catch 块中:

declare @res2 varchar(10)
declare @error_message varchar(max)
begin try
    exec test_output …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql parameter error-handling

8
推荐指数
1
解决办法
4120
查看次数