SQL Server:仅显示条件相关列不为null的行
是的,我已经为此奋斗了一段时间,尽管我有一个有效的问题,但它让我感到不符合逻辑。如果我表现出我的意思,会更容易: 我有一个包含工作ID、电子邮件地址和布尔值“应该使用”列的表SQL Server:仅显示条件相关列不为null的行,sql,sql-server-2008,reference,concatenation,Sql,Sql Server 2008,Reference,Concatenation,是的,我已经为此奋斗了一段时间,尽管我有一个有效的问题,但它让我感到不符合逻辑。如果我表现出我的意思,会更容易: 我有一个包含工作ID、电子邮件地址和布尔值“应该使用”列的表 CREATE TABLE LWEmail (ID int, Email varchar(64), MustUse int) INSERT INTO LWEmail VALUES(1,'adfgae@asfdvaerg.com',1) INSERT INTO LWEmail VALUES(1,'sdfghsth@asfdv
CREATE TABLE LWEmail
(ID int, Email varchar(64), MustUse int)
INSERT INTO LWEmail VALUES(1,'adfgae@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(1,'sdfghsth@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(1,'admjury@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(2,'dyj@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(2,'adynee@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(3,'kitu@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(3,'aswtrhe@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(3,'abetr@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(3,'aeryje@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(3,'eyj@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(4,'dej@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(4,'aetyj@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(4,'ey@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(5,'egn@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(5,'egrn@asfdvaerg.com',0)
INSERT INTO LWEmail VALUES(6,'bneyh@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(6,'eryh@asfdvaerg.com',1)
INSERT INTO LWEmail VALUES(6,'adfeyj@asfdvaerg.com',0)
以及根据“MustUse”条件将这些电子邮件地址连接到每个ID的一行的查询:
SELECT DISTINCT
CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF((SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and [MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Emails
FROM [LWEmail]
这将产生:
LOGBATCH EMAILS
1 adfgae@asfdvaerg.com, sdfghsth@asfdvaerg.com
2 (null)
3 kitu@asfdvaerg.com, aswtrhe@asfdvaerg.com, abetr@asfdvaerg.com
4 dej@asfdvaerg.com, aetyj@asfdvaerg.com
5 (null)
6 bneyh@asfdvaerg.com, eryh@asfdvaerg.com
如果“Emails”返回空的第2行和第5行,我还希望它忽略该行
因此,逻辑上我试图补充:
WHERE Emails IS NOT NULL
最后。“无效列名电子邮件”无效。但这确实有效:
SELECT DISTINCT
CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF((SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and [MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Email
FROM [LWEmail]
WHERE
STUFF((SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and [MustUse] = 1
FOR XML PATH('')), 1,2,'') IS NOT NULL
为什么我不能将“电子邮件”作为一个条件引用,而我会认为,由于括号和逻辑顺序,执行路径将使其成为第一个要执行的事情之一,使其可用于评估?您可以通过转换日期或数学运算来实现这一点。有什么见解吗?为了提高效率,我更愿意参考和评估已经计算过的内容,而不是重复计算两次。只是想学习和提高效率。你说的是逻辑顺序,但逻辑上,SELECT在WHERE之后执行。您可以将其放入子查询中:
SELECT * FROM (
SELECT DISTINCT
CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF((SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and [MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Emails
FROM [LWEmail]
) t
where Emails is not null
有关处理顺序,请参见Wikipedia上的示例:
从…起
在…上
哪里
分组
有
选择
不同的
订购人
此外:
为了提高效率,我更愿意参考和评估已经计算过的内容,而不是重复计算两次
SQLServer已经掌握了很多技巧,它可以观察到同一计算被要求两次,并且可以避免实际执行多次计算。另一方面,仅仅因为一个计算在您的语句中只出现一次,并不能保证系统不会对它进行多次实际计算
在这种情况下,我同意减少它只是因为它看起来很凌乱。但是您应该知道,在SQL语言中,您通常试图告诉系统您想要什么,而不是如何做。这就是优化器的工作。您说的是逻辑顺序,但逻辑上,SELECT在WHERE之后执行。您可以将其放入子查询中:
SELECT * FROM (
SELECT DISTINCT
CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF((SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and [MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Emails
FROM [LWEmail]
) t
where Emails is not null
有关处理顺序,请参见Wikipedia上的示例:
从…起
在…上
哪里
分组
有
选择
不同的
订购人
此外:
为了提高效率,我更愿意参考和评估已经计算过的内容,而不是重复计算两次
SQLServer已经掌握了很多技巧,它可以观察到同一计算被要求两次,并且可以避免实际执行多次计算。另一方面,仅仅因为一个计算在您的语句中只出现一次,并不能保证系统不会对它进行多次实际计算
在这种情况下,我同意减少它只是因为它看起来很凌乱。但是您应该知道,在SQL语言中,您通常试图告诉系统您想要什么,而不是如何做。这就是优化器的工作。显然,您不能在同一级别上创建的WHERE子句上调用别名。SQL的操作顺序如下: FROM子句 WHERE子句 分组依据子句 有从句 SELECT子句别名在此处创建 按条款订货 别名是在SELECT子句上创建的,WHERE子句首先执行。要从alias调用的唯一解决方案是将整个查询包装在子查询中。例如
SELECT *
FROM
(
SELECT DISTINCT CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF(( SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and
[MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Emails
FROM [LWEmail]
) subQuery
WHERE Emails IS NOT NULL
显然,不能对在同一级别上创建的WHERE子句调用别名。SQL的操作顺序如下: FROM子句 WHERE子句 分组依据子句 有从句 SELECT子句别名在此处创建 按条款订货 别名是在SELECT子句上创建的,WHERE子句首先执行。要从alias调用的唯一解决方案是将整个查询包装在子查询中。例如
SELECT *
FROM
(
SELECT DISTINCT CONVERT (varchar(24), [LWEmail].[ID]) AS LogBatch,
STUFF(( SELECT CAST(', ' + LWEmail2.Email AS VARCHAR(MAX))
FROM [LWEmail] AS LWEmail2
WHERE LWEmail2.[ID] = [LWEmail].[ID] and
[MustUse] = 1
FOR XML PATH('')), 1,2,'') AS Emails
FROM [LWEmail]
) subQuery
WHERE Emails IS NOT NULL
尝试:
尝试:
这很容易解决!我知道这很简单,只需要强制创建“Email”列,就可以通过将WHERE设置为子查询来计算它。谢谢大家的快速回复!这很容易解决!我知道这很简单,只需要强制创建“Email”列,就可以通过将WHERE设置为子查询来计算它。谢谢大家的快速回复!是的,已经完成了一系列程序化的java、C++等,很难在没有经过思维过程的情况下移动到一种操纵语言。谢谢你的额外信息。是的,已经做了一些程序化的java、C++等,很难在没有经过思维过程的情况下移动到一个操纵语言。谢谢你提供的额外信息。