有很多解释为什么 NOT IN NULL 不起作用,但我没有看到任何解决方案。(最近的问题在这里:为什么 NOT IN 包含 NULL 的集合总是返回 FALSE/NULL?)
我有 6 个存储过程的可选参数,用于过滤查询的某个值。以前的开发人员做了这样的事情:
IF @var1 IS NULL AND .....
select ...
else
select ...
where value in (@var1, ...)
Run Code Online (Sandbox Code Playgroud)
我不是特别喜欢这个。(查询非常庞大),所以我决定选择这样的东西:(
无论如何,我们在临时表中得到了结果)
IF @var IS NOT NULL OR ...
delete from #temp where value not in (@var1,...)
Run Code Online (Sandbox Code Playgroud)
但我意识到这行不通。
我唯一能想到的就是创建另一个临时表,该表将只保存@var1 等中的非空值(使用 if 语句或删除 where 为 NULL),然后对该表进行连接删除。
有没有更好的办法?
我需要能够提取允许 NULL 值的列名,我知道
show columns from TABLE
Run Code Online (Sandbox Code Playgroud)
将显示表属性以及该列是否允许空值,但是有没有办法只返回允许空值的列名。
show columns from TABLE where Null = 'YES' 不起作用,但它解释了我需要完成的工作。
当然,很容易把所有东西都拉出来,然后再整理出来,但是如果有办法做我要问的事情,我想学习它。
我有两个日期列:“开始日期”和“完成日期”。
我想确保对于一个主键(在我的情况下是复合键),“完成日期”列中只能有一个空值(如果它是 NULL,则应该是当前状态)。有没有办法做到这一点?
为了说明这一点,主键的一部分应该只有一个 NULL。以下是列:
PeriodID | PersonID | StartDate | FinishDate
1 1 1/1/10 10/1/10
2 1 10/1/10 NULL
3 1 somedate MUST NOT BE NULL
Run Code Online (Sandbox Code Playgroud)
是的,“PersonID”是外键。
我正在使用 SQL Server 2008。
编辑 :
我得到了一个有效的答案,但其他方式也很好。
我有 4 个子查询,每个子查询都按“组名”分组。尝试将每个子查询作为一个列,全部按“组名”分组。这是查询:
select
coalesce(co.group_name, requests.group_Name, incidents.group_Name, problems.group_Name) as 'SD Groups'
, isnull(co.co, '') as 'CO'
, isnull(incidents.incidents, '' ) as 'Inc'
, isnull(problems.problems, '') as 'Prob'
, isnull(requests.requests, '') as 'Rqst'
from
(
select
groups.last_name AS Group_Name
,count(chg_ref_num) AS 'CO'
from chg
left join ca_contact groups
on chg.group_id = groups.contact_uuid
left join ca_contact assignee
on chg.assignee = assignee.contact_uuid
left join ca_company cc
on assignee.company_uuid = cc.company_uuid
where
groups.last_name in ('8197 Qlikview Support', '8202 OBIEE-BIP'
, '8205 BI SAS', '8206 …Run Code Online (Sandbox Code Playgroud) 我想创建一个ID默认情况下自动生成唯一 ID 号的列。
用户不会通过INSERT语句插入行,而是使用开箱即用的应用程序(使用属性编辑环境)创建行。
我听说可以通过创建Oracle IDENTITY 列来实现自动生成的 ID
(提示:要在链接页面中查找相关部分,请搜索此文本:)Use this clause to specify an identity column.。
因此,我已成功创建了一个带有IDENTITY列的表:
CREATE TABLE A_TEST_TABLE (ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY);
Run Code Online (Sandbox Code Playgroud)
但是,我看到该字段不是 nullabe:
SELECT ID FROM ALL_TAB_COLUMNS WHERE TABLE_NAME = 'A_TEST_TABLE'
NULLABLE = N
Run Code Online (Sandbox Code Playgroud)
这是一个问题,因为我的应用程序试图“帮用户一个忙”。如果字段不可为空,应用程序会自动插入一个零作为虚拟值。这会覆盖自动生成的 ID(这当然不是我想要的)。我猜测这样做是为了避免在提交空值时从数据库收到错误消息。
为了避免我的应用程序出现此问题,是否可以将字段设为 nullabe?
当我阅读文档时,它说:
如果您指定 ON NULL,那么当后续的 INSERT 语句尝试分配计算结果为 NULL 的值时,Oracle 数据库使用序列生成器为该列分配一个值。
这是否意味着IDENTITY字段可以为空?如果是这样,如何?
我承认我不知道自己在做什么。我什至不认为我最终会想要一个可以为空的 ID …
我有一些列代表表格中的年龄,取值从 0 到 100,但也有 -1 表示“缺失值”。我不想将它们存储为字符串以便能够找到平均年龄等,但是 SSAS 默认将 0 变为 NULL,并且我也想将 -1 替换为 NULL,因此有经典的“重复属性键”错误。
是否有正确的方法/类型来处理年龄值?
选项1:
CREATE PROCEDURE [dbo].[GetStudents]
@MinimumAge int = NULL
AS
select * from Students s where @MinimumAge is null or s.Age >= @MinimumAge
Run Code Online (Sandbox Code Playgroud)
选项2:
CREATE PROCEDURE [dbo].[GetStudents]
@MinimumAge int = NULL
AS
IF @MinimumAge IS NULL
BEGIN
select * from Students s
END
ELSE
BEGIN
select * from Students s where s.Age >= @MinimumAge
END
Run Code Online (Sandbox Code Playgroud)
选项 1 会因为有额外的WHERE子句而比选项 2 慢吗?或者 SQL Server 会处理这个问题吗?
我认为选项 1 很好,因为我不必重复代码,除非它速度较慢。原来的程序有很多行代码。因此,我不想仅针对一种条件重复所有代码,除非这是唯一的好选择。
该列有索引age,并且不允许空值。
问题是,实际 SP 有很多行代码 - 所以我不想复制所有代码只是为了添加一个 where 条件,除非这是唯一好的选择。
performance null sql-server stored-procedures query-performance
这个问题中的 SQL 是针对 Oracle 的。但是您可以简单地删除FROM dual以使其在 SQL Server 上工作(它返回与 Oracle 相同的结果)。
我有以下 SQL:
SELECT 1
FROM dual
WHERE NULL IN (SELECT 1 FROM dual WHERE 1 = 0);
SELECT 1
FROM dual
WHERE NULL NOT IN (SELECT 1 FROM dual WHERE 1 = 0);
Run Code Online (Sandbox Code Playgroud)
它分别返回一个空集和 1。当我们用其他值代替 时NULL,我们得到了完全相同的结果。
SELECT 1
FROM dual
WHERE 33 IN (SELECT 1 FROM dual WHERE 1 = 0);
SELECT 1
FROM dual
WHERE 33 NOT IN (SELECT 1 FROM dual WHERE 1 …Run Code Online (Sandbox Code Playgroud) 我们有一个表结构,父记录和子记录位于同一个表中。它们通过列 ( parentId ) 引用,该列引用父记录(顶部父记录上为 null)。此外,我们有一个请求的日期列,我们通过该列进行所有查询,但唯一具有此值的记录是父记录。
由于我们所有的查询最初都是根据父结果进行过滤并使用此日期,因此我们希望在此日期范围内对表进行分区,但我们知道这是不可能的,因为子记录的记录中存在空值。
除了在数据库中的每个子记录上创建一个“虚拟”值(一些永远不会在我们的过滤器中捕获的任意日期)之外,我们还有什么其他选择?是否不可能以某种方式为我们从未查询过的所有空值创建一个单独的分区?
我有以下查询,我正在查找该列不等于 1 的任何行istrue。但结果只包含 0 的记录,忽略 null 的记录。虽然我知道使用(istrue != 1 or istrue is null)会产生预期的结果,但我很好奇导致 SQL Server 排除 null 值的底层机制。您能否提供对此行为的见解?谢谢!
create table #test
(
id int,
val varchar(100),
istrue bit
)
insert into #test values
(1, 'test-1', 1),
(2, 'test-2', 0),
(3, 'test-3', 1),
(4, 'test-4', 0),
(5, 'test-5', null),
(6, 'test-6', null)
select * from #test
where istrue != 1
drop table if exists #test
Run Code Online (Sandbox Code Playgroud) null ×10
sql-server ×6
oracle ×2
constraint ×1
except ×1
group-by ×1
identity ×1
join ×1
mysql ×1
partitioning ×1
performance ×1
postgresql ×1
query ×1
ssas ×1
ssis ×1
sybase ×1