标签: t-sql

为什么我的 STRING_AGG 中的 ORDER BY 并不总是有效?

我有一个表,其中包含记录 ID、组 ID(将 1 个或多个记录链接到一个组中)以及每个记录的哈希值。

CREATE TABLE HashTable(
    RecordID VARCHAR(255),
    GroupIdentifier VARCHAR(255),
    Hash VARCHAR (255),
    GroupHashList VARCHAR(4000)
)
Run Code Online (Sandbox Code Playgroud)

(我知道这不是一个有效的表,但它只是用于本示例的临时表)。

我想为每个组生成一个哈希值,所以我认为最简单的方法是连接组中每个记录的哈希值。RecordID 是唯一的,但这些记录所涉及的内容不一定是唯一的,因此散列可能是重复的。这样做的目的是标记完全重复的组,即该组中的所有记录都是另一组中的所有记录的重复项的组。如果 GUI 要将组中的所有成员识别为重复组,则需要该组的所有成员具有相同的哈希值。

我使用 STRING_AGG 连接组中记录的各个散列,并按散列对它们进行排序,以确保我为重复的组获得相同的字符串。我实际上并不关心哈希的顺序是什么,只要每次都相同即可。当我将其作为 SELECT 查询运行时,它工作正常,并且我可以看到重复组的相同字符串。当我采用相同的 SELECT 查询并将其放入 UPDATE 查询中时,顺序似乎丢失了。

SELECT STRING_AGG([Hash],';') WITHIN GROUP (ORDER BY [Hash] ASC) 
FROM HashTable
GROUP BY [GroupIdentifier]
Run Code Online (Sandbox Code Playgroud)

这给出了结果(对于一对重复组的示例):

CREATE TABLE HashTable(
    RecordID VARCHAR(255),
    GroupIdentifier VARCHAR(255),
    Hash VARCHAR (255),
    GroupHashList VARCHAR(4000)
)
Run Code Online (Sandbox Code Playgroud)

当我将相同的代码放入 UPDATE 查询中时,它无法正确对它们进行排序:

UPDATE HashTable
SET GroupHashList = c.HashList
FROM HashTable
INNER JOIN (
    SELECT (STRING_AGG([Hash],';') WITHIN GROUP (ORDER BY [Hash] …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql string-aggregation

21
推荐指数
1
解决办法
8347
查看次数

使用 SQL Server 中另一个表中的值更新表

我的数据库中有 2 个表。

表格1

-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

表#2

-----------------------------------------
| gender | address | phone | birthdate |
-----------------------------------------
Run Code Online (Sandbox Code Playgroud)

在表#1的列地址PHONE2是空的和列性别生日的值是相同的表#2。

当每行的性别出生日期相同时,如何从表 #2 中读取数据并使用表 #2 addressphone列中的值更新表 #1 中的addressphone2

例如:这是表 #1 中的一些数据

-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address …
Run Code Online (Sandbox Code Playgroud)

join sql-server t-sql update sql-server-2014

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

为什么我不能像我想象的那样在 T-SQL 中使用变量?

原谅我,我是一名已经转向 SQL 世界的开发人员。我以为我可以通过添加变量来改进一些 SQL,但它并没有像我预期的那样运行。有人能告诉我为什么这不起作用吗?我不想解决问题,我想知道为什么这不像我想象的那样工作,因为我确信有一个很好的理由,但目前它并没有跳出来。

DECLARE @DatabaseName varchar(150)
SET @DatabaseName = 'MyAmazingDatabaseName'

CREATE DATABASE @DatabaseName
GO

USE @DatabaseName
GO
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 t-sql

20
推荐指数
3
解决办法
4335
查看次数

默认约束,值得吗?

我通常按​​照以下规则设计我的数据库:

  • 除了 db_owner 和 sysadmin 之外,没有其他人可以访问数据库表。
  • 用户角色在应用层控制。我通常使用一个 db 角色来授予对视图、存储过程和函数的访问权限,但在某些情况下,我添加了第二条规则来保护一些存储过程。
  • 我使用 TRIGGERS 来初步验证关键信息。

CREATE TRIGGER <TriggerName>
ON <MyTable>
[BEFORE | AFTER] INSERT
AS
    IF EXISTS (SELECT 1 
               FROM   inserted
               WHERE  Field1 <> <some_initial_value>
               OR     Field2 <> <other_initial_value>)
    BEGIN
        UPDATE MyTable
        SET    Field1 = <some_initial_value>,  
               Field2 = <other_initial_value>  
        ...  
    END
Run Code Online (Sandbox Code Playgroud)
  • DML 使用存储过程执行:

sp_MyTable_Insert(@Field1, @Field2, @Field3, ...);
sp_MyTable_Delete(@Key1, @Key2, ...);
sp_MyTable_Update(@Key1, @Key2, @Field3, ...);
Run Code Online (Sandbox Code Playgroud)

您认为,在这种情况下,使用 DEFAULT CONSTRAINT 是否值得,或者我正在向数据库服务器添加额外且不必要的工作?

更新

我知道通过使用 DEFAULT 约束,我向必须管理数据库的其他人提供了更多信息。但我最感兴趣的是性能。

我假设数据库总是检查默认值,即使我提供了正确的值,因此我做了两次相同的工作。

例如,有没有办法在触发器执行中避免 DEFAULT 约束?

performance database-design sql-server t-sql default-value query-performance

20
推荐指数
2
解决办法
4415
查看次数

无法将“CO2”更新为“CO”?在表格行中

鉴于此表:

CREATE TABLE test (
    id INT NOT NULL,
    description NVARCHAR(100) COLLATE Modern_Spanish_CI_AS NOT NULL
);
INSERT INTO test (id, description) VALUES (1, 'CO2');
Run Code Online (Sandbox Code Playgroud)

我意识到我无法解决排版问题:

SELECT * FROM test WHERE id = 1;
UPDATE test SET description = 'CO?' WHERE id = 1;
SELECT * FROM test WHERE id = 1;
Run Code Online (Sandbox Code Playgroud)

因为更新匹配但没有效果:

id          description
----------- -----------
1           CO2

(1 affected rows)

(1 affected rows)

id          description
----------- -----------
1           CO2

(1 affected rows)
Run Code Online (Sandbox Code Playgroud)

就好像 SQL Server 确定了这一点,因为? 显然只是一个很小的2 …

sql-server collation t-sql sql-server-2008-r2 unicode

20
推荐指数
2
解决办法
4044
查看次数

为什么 SELECT 1/2 返回 0?

正如标题所说。我什至尝试过SELECT CONVERT(NUMERIC, 1/2)也返回0。

我正在使用 SQL Server 2008。

sql-server-2008 sql-server t-sql

19
推荐指数
2
解决办法
8343
查看次数

创建一个计划指南来缓存(懒惰假脱机)CTE 结果

我通常通过首先构造一个使用正确计划的查询,然后将其复制到类似的查询中来创建计划指南。但是,这有时很棘手,尤其是在查询不完全相同的情况下。从头开始创建计划指南的正确方法是什么?

SQLKiwi 已经提到在 SSIS 中制定计划,有没有一种方法或有用的工具来帮助为 SQL Server 制定一个好的计划?

有问题的具体实例是这个 CTE:SQLFiddle

with cte(guid,other) as (
  select newid(),1 union all
  select newid(),2 union all
  select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Run Code Online (Sandbox Code Playgroud)

有没有任何方法来使结果拿出正好3个不同的guidS和没有更多?我希望将来能够通过包含多次引用的 CTE 类型查询的计划指南来更好地回答问题,以克服一些 SQL Server CTE 怪癖。

sql-server cte t-sql

19
推荐指数
1
解决办法
2882
查看次数

分页性能,可自定义排序数百万行

在我们的应用程序中,我们有一个网格,用户可以在其中翻阅大量记录(10-2000 万)。网格支持在多列 (20+) 中按升序和降序排序。许多值也不是唯一的,因此应用程序还按 id 排序作为决胜局,以确保行始终出现在同一页面上。例如,如果用户想要按小部件大小(从最大的开始)排序,应用程序会生成一个看起来像这样的查询:

SELECT TOP 30
    * -- (Pretend that there is a list of columns here)
FROM Test
--  WHERE widgetSize > 100
ORDER BY
    widgetSize DESC,
    id ASC
Run Code Online (Sandbox Code Playgroud)

此查询需要大约 15 秒才能运行(使用缓存数据),主要成本似乎是按小部件大小对大约 130 万行进行排序。在尝试调整此查询时,我发现如果我添加一个WHERE仅限于最大 widgetSizes的子句(在上面的查询中注释掉),则查询只需要约 800 毫秒(所有前 50,000 个结果的小部件大小都大于 100) .

为什么没有WHERE子句的查询速度会如此之慢?我检查了 widgetSize 列的统计数据,它们显示前 739 行的 WidgetSize > 506。由于只需要 30 行,SQL Server 可以不使用此信息来推断它只需要对具有小部件大小的行进行排序哪个大?

查询的快速和慢速版本的查询执行计划的屏幕截图

我知道我可以通过在和上添加索引来使这个特定查询更快地执行,但是这个索引只在这个特定场景中有用,并且如果(例如)用户反转排序方向就变得毫无价值。该表包含许多附加列,并且每个索引都很大(~200mb),因此我无法为每个可能的排序顺序添加索引。widgetSizeid

有什么方法可以让这些查询查询执行而不为每个可能的排序顺序添加索引?(用户可以按 20 多列中的任何一列进行排序)


以下脚本创建上表并用一些代表性数据填充它。该表比实际表窄得多,但仍然展示了我所看到的性能。在我的 PC 上,带有 where 子句的查询需要约 200 毫秒,而没有 where caluse 的查询需要约 800 …

sql-server t-sql sorting paging

19
推荐指数
2
解决办法
4122
查看次数

在 SQL Server 中本地解码 Base64 字符串

varchar在 SQL Server 的表中有一个列,其中包含一个 base64 编码的文本字符串,我想将其解码为纯文本等效项

SQL Server 是否具有处理此类事情的任何本机功能?

一个示例 base64 字符串:

cm9sZToxIHByb2R1Y2VyOjEyIHRpbWVzdGFtcDoxNDY4NjQwMjIyNTcxMDAwIGxhdGxuZ3tsYXRpdHVkZV9lNzo0MTY5ODkzOTQgbG9uZ2l0dWRlX2U3Oi03Mzg5NjYyMTB9IHJhZGl1czoxOTc2NA==
Run Code Online (Sandbox Code Playgroud)

解码为:

role:1 producer:12 timestamp:1468640222571000 latlng{latitude_e7:416989394 longitude_e7:-738966210} radius:19764
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2008-r2 cast string-manipulation

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

限制对某些列的更新。只允许存储过程更新那些列

我有敏感的价格列,我只想通过存储过程进行更新。如果不使用旨在更新它的存储过程,我希望所有代码或手动尝试更改这些价格列中的值都失败。

我正在考虑使用触发器和令牌表来实现这一点。我正在考虑的想法是有一个令牌表。存储过程必须首先在令牌表中插入值。然后更新价格列。更新触发器将检查更新行的令牌表中是否存在该令牌。如果找到,它将继续。如果未找到令牌,则会抛出异常并使更新事务失败。

有没有好的/更好的方法来实现这个限制?

trigger sql-server stored-procedures t-sql sql-server-2012

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