我重新组织了数据库中的一些表以使其更加灵活,但我不确定如何编写 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) 所以基本上在 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 变得非常难看。我的程序与表定义无关,这意味着我不在乎你的表中有什么,也不想知道你的表的定义是什么。我只是想让你选择一个表格,选择一些字段来过滤等于、不等于、在、不在等......
阅读数据加载性能指南 后,我仍然不确定是否有必要将 TABLOCK 表提示添加到使用聚集索引定义的空临时表中,以便获得最少的日志记录。
显然,临时表是在 TempDB 中创建的,它在 SIMPLE 恢复模式下运行,所以我认为它是最小日志记录的完美候选者;然而,我找不到一段话来证实它。
临时表是否是最小日志记录的候选者,如果是,是否值得为永久表添加 TABLOCK 提示?
我得到的行比我期望的查询返回的行多。
我相信这与我的 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) 添加 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
我们有一个非常大(1 亿行)的表,我们需要更新其中的几个字段。
对于日志运输等,我们显然也希望将其保持为一口大小的交易。
代码是:
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) 我已经在下面创建了过滤索引,但是当我进一步运行 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
我有一个带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 中此命令的语法是什么?
我想将表中的数据选择为 4 组,该表具有尽可能均匀分布的组中值的总和。我敢肯定我解释得不够清楚,所以我会尝试举一个例子。
这里我使用 NTILE(4) 创建 4 个组:
SELECT Time, NTILE(4) OVER (ORDER BY Time DESC) AS N FROM TableX
Time - N
-------------
10 - 1
9 - 2
8 - 3
7 - 4
6 - 1
5 - 2
4 - 3
3 - 4
2 - 1
1 - 2
Run Code Online (Sandbox Code Playgroud)
在上面的查询和结果中,为简洁起见,省略了其他列。
所以你也可以看到这些组如下:
1 2 3 4
--- --- --- ---
10 9 8 7
6 5 4 3
2 1
--- --- --- ---
18 15 …Run Code Online (Sandbox Code Playgroud) 最近,我接到了打印所有质数(1-100)的任务。我在那里彻底失败了。我的代码:
Create Procedure PrintPrimeNumbers
@startnum int,
@endnum int
AS
BEGIN
Declare @a INT;
Declare @i INT = 1
(
Select a = @startnum / 2;
WHILE @i<@a
BEGIN
@startnum%(@a-@i)
i=i+1;
)
END
Run Code Online (Sandbox Code Playgroud)
虽然我最终没有完成它,但我想知道在数据库(SQL Server 2008 R2)上做这样的程序是否可行。
如果是,它会如何结束。
t-sql ×10
sql-server ×8
performance ×3
deadlock ×1
foreign-key ×1
import ×1
index ×1
join ×1
null ×1
optimization ×1
pivot ×1