有没有办法检查另一个数据库中是否存在索引?
AFAIK,通常的方法(sys.indexes
和)仅在当前INDEXPROPERTY
数据库的上下文中运行。
有没有办法检查另一个数据库中是否存在索引?
AFAIK,通常的方法(sys.indexes
和)仅在当前INDEXPROPERTY
数据库的上下文中运行。
是否可以从没有N
前缀的损坏的 nvarchar 中恢复 UTF8 数据?
例如,在以下代码段中,我希望@n1_fixed
基于以下内容获得正确的值@n1
:
declare
@n1 nvarchar(10) = 'Ḿấxiḿứś',
@n2 nvarchar(10) = N'Ḿấxiḿứś';
declare
@n1_fixed nvarchar(10); -- somehow make it have the correct value, based on @n1
select iif(@n1_fixed = @n2, 1, 0)
有没有一种聪明的方法来计算有多少变量等于某个目标值(在 SQL Server 中)?
例如,如果我有:
declare @a int = 1;
declare @b int = 2;
declare @c int = 1;
declare @target int = 1;
然后我想做多少个@a, @b, @c
eqauls @target
。
在命令式语言中,很容易创建一个内联变量数组,然后计算它们——例如在 JS 中:
var a = 1, b = 2, c = 2, target = 1;
if ([a, b, c].filter(item => item == target).length == 1)
// do something
该“内联数组”在 SQL 中的等价物将是一个单列表,但这需要 using DECLARE TABLE
,我想避免这种情况。
在 SQL 中是否有类似的简单方法来进行此类计数?
请注意,我对“在不声明的情况下创建表”不太感兴趣——我真正关心的是根据目标变量计算变量,所以如果可以在完全不使用表的情况下完成,那就更好了。
应如何WHERE
构造子句,例如:
例如,如果我们有这个模式:
CREATE TABLE Items
(
[Id] INT PRIMARY KEY,
[FirstDate] DATETIME,
[SecondDate] DATETIME
);
...有这些记录:
INSERT INTO Items ([Id], [FirstDate], [SecondDate])
VALUES
(1, '2021-1-1', '2022-1-1'),
(2, '2022-1-1', '2023-1-1'),
(3, '2022-1-1', '2024-1-1'),
(4, '2024-1-1', '2025-1-1'),
(5, '2024-1-1', '2026-6-1')
...然后我想过滤FirstDate
and SecondDate
,这样:
FirstDate
andSecondDate
来过滤2022-1-1
,将返回记录 2 和 3(但不是 1!)。FirstDate
andSecondDate
来过滤2024-1-1
,将返回记录 4 和 5(但不是 3!)。FirstDate
andSecondDate
来过滤2025-1-1
,将返回记录 4。我有一个父子表关系,我试图让每个父行及其最新的子行详细信息。
我尝试使用子查询来做到这一点没有奏效,我只能使用 CTE 来做到这一点。
我想了解:
这是父子关系的玩具示例(完整演示在这里):
CREATE TABLE Cities
(
[Id] INT PRIMARY KEY,
[Name] NVARCHAR(100),
[EstablishedDate] DATETIME2 NULL,
);
CREATE TABLE Parks
(
[Id] INT PRIMARY KEY,
[Name] NVARCHAR(100),
[OpeningDate] DATETIME2 NULL,
[CityId] INT FOREIGN KEY REFERENCES Cities(Id)
);
使用 CTE 成功查询:
;WITH NumberedParks AS
(
SELECT *, ROW_NUMBER() OVER (PARTITiON BY CityId ORDER BY OpeningDate DESC) AS rownum
FROM Parks
)
SELECT *
FROM Cities
JOIN NumberedParks on Cities.Id = NumberedParks.CityId
WHERE rownum = 1;
失败的尝试:
SELECT *
FROM Cities
JOIN Parks on Cities.Id = Parks.CityId
WHERE EXISTS
(
SELECT TOP 1 Id
FROM Parks inner_parks
WHERE inner_parks.Id = Parks.Id
ORDER BY inner_parks.OpeningDate DESC
)
SELECT *
FROM Cities
JOIN Parks on Cities.Id = Parks.CityId
WHERE Parks.Id =
(
SELECT TOP 1 Id
FROM Parks inner_parks
WHERE inner_parks.Id = Parks.Id
ORDER BY inner_parks.OpeningDate DESC
);
在以下脚本中(请参阅此处的完整演示):
SELECT *
FROM Table1
ORDER BY
CASE WHEN Field1 IS NOT NULL
THEN 0
END
0
什么?0
解释的?不是选择列表中列的序号,因为选择列表枚举是从 1 开始的,而不是 0。那么它是什么?为了详细说明,将上面的代码段与以下代码段进行比较,它会发出错误:
SELECT *
FROM Table1
ORDER BY 0
ORDER BY 位置编号 0 超出了选择列表中的项目数范围。
并将其与以下代码段进行比较,该代码段会发出另一个错误:
SELECT *
FROM Table1
ORDER BY '0'
在 ORDER BY 列表的位置 1 中遇到常量表达式。
似乎将0
值嵌套在case
子句下使它起作用,但我不明白为什么以及如何?
我需要一个简单的查询,但找不到方法:
我有一张客户购买的服务表,其中不同的客户可能会购买相同的服务(很简单),每个客户可能有几个活跃或不活跃的服务:
ServiceId IsActive ServiceCustomerId
815 0 111
715 0 111
985 1 222
815 1 333
475 1 111
985 1 111
815 1 222
我想获取同时拥有活动和非活动服务的客户的记录,因此输出将是(ServiceId
可以省略):
IsActive ServiceCustomerId
0 111
1 111
我所拥有的是:
select ServiceCustomerId,IsActive from Services
group by ServiceCustomerId, IsActive
having count(IsActive) > 1
order by ServiceCustomerId
这使:
IsActive ServiceCustomerId
0 111
1 111
1 222
如何仅过滤同时具有这两个IsActive
组的人?
我想将 aJSON_QUERY
与SELECT TOP 1
查询一起使用,以便生成的 json 以对象形式而不是表形式具有前 1 条记录?
例如,以下查询(现场演示):
CREATE TABLE Trees
(
[Id] INT,
[Type] NVARCHAR(100),
[Height] DECIMAL(2,1)
);
INSERT INTO Trees ([Id], [Type], [Height])
VALUES
(1, 'Palm', 5.5),
(2, 'Pine', 6.2),
(3, 'Apple', 2.5),
(4, 'Japanese Cedar', 0.5),
(5, 'Spanish Fir', 0.6);
SELECT
highestTree = JSON_QUERY(
(
SELECT TOP 1
Id as id,
Type as type,
Height as height
FROM Trees
WHERE Height = (SELECT Max(Height) FROM Trees)
FOR JSON PATH
)
),
lowestTree = JSON_QUERY(
(
SELECT TOP 1
Id as id,
Type as type,
Height as height
FROM Trees
WHERE Height = (SELECT MIN(Height) FROM Trees)
FOR JSON PATH
)
)
FOR JSON
PATH, WITHOUT_ARRAY_WRAPPER
;
输出:
{"highestTree":[{"id":2,"type":"Pine","height":6.2}],"lowestTree":[{"id":4,"type":"Japanese Cedar","height":0.5}]}
但我想要:
{"highestTree":{"id":2,"type":"Pine","height":6.2},"lowestTree":{"id":4,"type":"Japanese Cedar","height":0.5}}
我有一个FOR JSON
表达式的结果,我想将它插入到一个表格列中。
我怎么做?
这是我的一次不成功的试验(请注意,该SELECT hightrees ... FOR JSON PATH
部分是正确的,可以在我的另一个问题的答案中看到,这也是现场演示),它给出了错误Invalid object name 'TreesJson'
:
SELECT * FROM (
SELECT
highTrees = JSON_QUERY(
(
SELECT
Id as id,
Type as type,
Height as height
FROM Trees WHERE [Height] > 5
FOR JSON PATH
)
),
lowTrees = JSON_QUERY(
(
SELECT
Id as id,
Type as type,
Height as height
FROM Trees WHERE [Height] < 1
FOR JSON PATH
)
)
FOR JSON
PATH, WITHOUT_ARRAY_WRAPPER
) AS TreesJson;
INSERT INTO TreesGrowthLog ([Day], [TreesGrowth])
VALUES (CAST(GETDATE() AS Date, (SELECT * FROM TreesJson FOR JSON AUTO))
我需要根据同一张表上两个不同查询的结果构造一个 json,其中连接是无关紧要的。
考虑以下示例(此处为完整演示):
CREATE TABLE Trees
(
[Id] INT,
[Type] NVARCHAR(100),
[Height] DECIMAL(2,1)
);
INSERT INTO Trees ([Id], [Type], [Height])
VALUES
(1, 'Palm', 5.5),
(2, 'Pine', 6.2),
(3, 'Apple', 2.5),
(4, 'Japanese Cedar', 0.5),
(5, 'Spanish Fir', 0.6);
我想构建以下json:
{
"highTrees":
[
{
"id": 1,
"type": "Palm",
"height": 5.5
},
{
"id": 1,
"type": "Pine",
"height": 6.2
}
],
"lowTrees":
[
{
"id": 4,
"type": "Japanese Cedar",
"height": 0.5
},
{
"id": 5,
"type": "Spanish Fir",
"height": 0.6
}
]
}
我试过这个:
SELECT
Id as 'highTrees.id',
Type as 'highTrees.type',
Height as 'highTrees.height'
FROM Trees WHERE [Height] > 5
UNION ALL
SELECT
Id as 'lowTrees.id',
Type as 'lowTrees.type',
Height as 'lowTrees.height'
FROM Trees WHERE [Height] < 1
FOR JSON PATH;
但显然这不是要走的路,因为它给出了这个:
[
{
"highTrees": {
"id": 1,
"type": "Palm",
"height": 5.5
}
},
{
"highTrees": {
"id": 2,
"type": "Pine",
"height": 6.2
}
},
{
"highTrees": {
"id": 4,
"type": "Japanese Cedar",
"height": 0.5
}
},
{
"highTrees": {
"id": 5,
"type": "Spanish Fir",
"height": 0.6
}
}
]
我怎样才能达到预期的效果?
我有下表,其中[Data]
是类型nvarchar(max)
,它的值是有效的 json 字符串:
ID | 数据 |
---|---|
1 |
{ "info" : { "done": true, "chosenOptions": ["one", "two"] } } |
2 |
{ "info" : { "done": true, "chosenOptions": ["one"] } } |
3 |
{ "info" : { "done": true, "chosenOptions": [] } } |
4 |
{ "info" : { "done": true } } |
我想更新所有Data
不包含chosenOptions
或 where chosenOptions
is 的行[]
。
Data
json 值都有几个其他属性,而不是此处显示的属性,如果这很重要的话。我的查询:
declare @defaultValue Nvarchar(100);
set @defaultValue = JSON_QUERY('["one", "two"]')
update myTable
set [Data] = JSON_QUERY(JSON_MODIFY([Data], '$.info.chosenOptions', @defaultValue))
where JSON_QUERY([data], '$.info.chosenOptions') IS NULL or
JSON_QUERY([data], '$.info.chosenOptions') = '[]'
结果chosenOptions
值是字符串而不是数组(请忽略数组值的转义,这在这里不太重要):
ID | 数据 |
---|---|
1 |
{ "info" : { "done": true, "chosenOptions": ["one", "two"] } } |
2 |
{ "info" : { "done": true, "chosenOptions": ["one"] } } |
3 |
{ "info" : { "done": true, "chosenOptions": "[\"one\", \"two\"]" } } <-- 注意它是一个字符串,而不是数组 |
4 |
{ "info" : { "done": true, "chosenOptions": "[\"one\", \"two\"]" } } <-- 注意它是一个字符串,而不是数组 |
我认为这是一种预期的行为,但是如何正确更新该数组?
据我了解文档,嵌套循环运算符是一个连接运算符,即它需要两个表作为输入。
如果这是正确的,那么为什么嵌套循环运算符与标量输入一起使用?
例如,采用以下查询(来自 Paul White 的网站)及其执行计划。您可以看到嵌套循环运算符的输入是 (1) 标量和 (2) 表(索引查找的结果)。
我知道标量不能与表连接,那么这实际上意味着什么?究竟加入了什么?
USE AdventureWorks2019;
DECLARE @Like nvarchar(50) = N'D%';
SELECT p.[Name]
FROM Production.Product AS p
WHERE p.[Name] LIKE @Like;
顺便说一句,我认为这是一个非常基本的问题,但我找不到一个很好的资源来从方法上讲这些基础知识,所以非常感谢推荐。
我正在学习执行计划,并且对表假脱机和相关子查询之间的关系有疑问(我正在关注本教程,不要介意拼写错误)。
我创建了下表:
CREATE TABLE student (
ID INT IDENTITY(1, 1),
CX_Name VARCHAR(50),
CX_PhoneNum VARCHAR(50),
CX_Address VARCHAR(MAX),
CX_Credit INT
)
然后插入值:
INSERT INTO student
VALUES (
'Alen',
'9625788954',
'London',
500
)
GO 100
INSERT INTO student
VALUES (
'Frank',
'962445785',
'Germany',
1400
)
GO 100
然后执行以下查询,其中包括一个相关的子查询:
SELECT ID, CX_Name, CX_Credit
FROM student CX1
WHERE CX_Credit >= (
SELECT AVG(CX_Credit)
FROM student CX2
WHERE CX1.ID = CX2.ID
)
执行计划是:
本教程解释(粗体是我的):
SQL Server Engine 先从表中读取数据,对数据进行排序,然后再将其划分为段,然后创建一个临时表来存储数据组。
在解释计划的另一部分,SQL Server 引擎从 Table Spool 中读取数据,然后使用 Stream Aggregate 运算符计算每个组的平均信用值。
最后一个 Table Spool 操作员将读取分组数据并将其连接以检索高于平均值的值。
三个 Table Spool 操作员将使用第一次创建的同一个临时表。
我不明白加粗的句子,有两种方式:
我有一列(名为RequestDate
),我需要将其从 更改NULL
为NOT NULL
,但该列上有一个聚集索引,因此我首先需要删除该索引。
最初,索引是使用以下方法创建的:
CREATE CLUSTERED INDEX IX_RequestDate
ON [MyDB].[dbo].[MyTable] (RequestDate);
为了放弃它,我执行了:
Drop Index IX_RequestDate On [MyDB].[dbo].[MyTable]
然后尝试使用以下方法更改列无效性:
ALTER TABLE [MyDB].[dbo].[MyTable] ALTER COLUMN [RequestDate] DATETIME NOT NULL
但出现错误:
对象“MyTable”依赖于列“RequestDate”。
MyTable
然后我使用这个查询列出了 的索引,并且索引仍然存在,尽管现在它没有名称并且它的类型是HEAP
(最初CLUSTERED
):
TableName IndexName IndexType ColumnOrdinal ColumnName ColumnType
MyTable NULL HEAP 0 RequestDate datetime
我有两个问题:
请注意,此表没有任何限制。
我正在使用 SQL Server 2014、OS Windows Server 2012 R2,以下是SCRIPT TABLE AS -> CREATE TO
(我更改了一些列名)的输出:
CREATE TABLE [dbo].[MyTable](
[RequestDate] [datetime] NULL,
[UserName] [nvarchar](50) NULL,
[HostName] [nvarchar](20) NULL,
[RequestContent] [ntext] NULL,
[ResponseContent] [ntext] NULL,
[RequestStatus] [int] NULL,
[ErrorMessage] [ntext] NULL,
[Duration] [float] NULL,
[ServiceName] [nvarchar](100) NULL,
[Direction] [int] NULL,
[RequestId] [uniqueidentifier] NOT NULL,
[IsRetry] [bit] NULL,
[CallerId] [nvarchar](100) NULL
)