使用 Left Join 时,如何显示区分空字符串值和不存在值的数据?
When Using Left Join, how do I present data differentiating between empty string-values and non-existing values?
我需要创建一个 table,其中包含来自不同数据库环境中不同 table 的列,并将它们与跨这些 table 的公共键匹配。其中许多值都有合理的理由为空,但在某些环境中它们甚至不存在,这是我需要确定的问题,可能通过插入自定义字符串,例如"\\NULL///"...
我有一组预生产环境,其中每个环境在 table 中都有很多配置参数,我已经将它们提取到一个巨大的 table.
中
我现在正在尝试编写一个 SQL 以在 2D-table 中呈现某些参数集(环境与参数 x-ref 值 table),以确定有问题的值,完全缺少一些参数。
SELECT x0.envName,
x1.param1,
x2.param2,
x3.param3
FROM ( ( (
(SELECT envName
FROM paramTable
GROUP BY envName) x0
LEFT JOIN
( SELECT envName,
parameterValue AS param1
FROM paramTable
WHERE parameterName='param1' ) x1 ON x1.envName = x0.envName )
LEFT JOIN
( SELECT envName,
parameterValue AS param2
FROM paramTable
WHERE parameterName='param2' ) x2 ON x2.envName = x0.envName )
LEFT JOIN
( SELECT envName,
parameterValue AS param3
FROM paramTable
WHERE parameterName='param3' ) x3 ON x3.envName = x0.envName)
如果我的参数表是这样的:
+ paramTable
=================================================
envName | paramName | paramValue |
-------------------------------------------------
env1 | param1 | abcdef |
env1 | param2 | 123456 |
env1 | param3 | A73BB2 |
env2 | param1 | klmnop |
env2 | param2 | 987654 |
env2 | param3 | |
env3 | param2 | uvwxyz |
然后,此查询的结果 table 将不会区分空字符串值(例如 env2 上的 param3)和不存在的值(例如 env3 中的 param1 和 param3):
+ ResultQueryResult
=================================================================
envName | param1 | param2 | param3 |
-----------------------------------------------------------------
env1 | abcdef | 123456 | A73BB2 |
env2 | klmnop | 987654 | |
env3 | | uvwxyz | |
我想以某种方式修改 SQL,以便结果查询会得到这样的结果:
+ PreferedQueryResult
=================================================================
envName | param1 | param2 | param3 |
-----------------------------------------------------------------
env1 | abcdef | 123456 | A73BB2 |
env2 | klmnop | 987654 | |
env3 | <<<!NULL!>>> | uvwxyz | <<<!NULL!>>> |
你可以简单地使用像 <<<!NULL!>>>
这样的特殊常量并更改:
select paramValue
来自
select nvl(paramValue,'<<<!NULL!>>>')
或添加一个布尔列(对于每个参数):
替换
select paramValue
来自
select
case when paramValue is null
then True
else False
end as isParamValueNull,
paramValue
在结果中包含来自内部 table 的 NOT NULL 字段。然后,当该字段为 NULL 时,您知道内部行不存在(与其 NULL-able 字段为 NULL 相反)。
当在必须为 NOT NULL 的主键上加入时,您可以使用其中一个 PK 字段(在您的情况下似乎是 envName
/paramName
)。否则,你可以 "invent" 你自己的非 NULL 字段,通过在子查询上加入:
...
LEFT JOIN (SELECT 1 inner_exists, <other fields> FROM inner ...) Q
ON ...
避免使用 "magic" 值,因为您永远不知道它们是否实际存在于真实数据中。或者,如果你走那条路,使用不太可能出现的东西,比如 GUID。
DECLARE @paramTable TABLE (envName varchar(15), parameterName varchar(15), parameterValue varchar(15) )
INSERT INTO @paramTable (envName, parameterName, parameterValue)
VALUES
('env1','param1','abcdef')
,('env1','param2','123456')
,('env1','param3','A73BB2')
,('env2','param1','klmnop')
,('env2','param2','987654')
,('env2','param3','' )
,('env3','param2','uvwxyz')
select x0.envName, ISNULL(x1.param1,'<<!NULL!>>') as param1, ISNULL(x2.param2,'<<!NULL!>>') as param2,ISNULL(x3.param3,'<<!NULL!>>') as param3
from
(
(
(
(select envName from @paramTable group by envName) x0
left join
(
select envName, parameterValue as param1 from @paramTable where parameterName='param1'
) x1
on x1.envName = x0.envName
)
left join
(
select envName, parameterValue as param2 from @paramTable where parameterName='param2'
) x2
on x2.envName = x0.envName
)
left join (
select envName, parameterValue as param3 from @paramTable where parameterName='param3'
) x3
on x3.envName = x0.envName
)
结果:
envName param1 param2 param3
--------------- --------------- --------------- ---------------
env1 abcdef 123456 A73BB2
env2 klmnop 987654
env3 <<!NULL!>> uvwxyz <<!NULL!>>
我试图重写您的查询:
SELECT x0.envName,
CASE WHEN x1.parameterName='param1' THEN x1.param1 ELSE '<<!NULL!>>' END AS param1,
CASE WHEN x1.parameterName='param2' THEN x1.param1 ELSE '<<!NULL!>>' END AS param2,
CASE WHEN x1.parameterName='param3' THEN x1.param1 ELSE '<<!NULL!>>' END AS param3
FROM (SELECT envName
FROM paramTable
GROUP BY envName) x0
LEFT JOIN paramTable x1
ON x1.envName = x0.envName
我需要创建一个 table,其中包含来自不同数据库环境中不同 table 的列,并将它们与跨这些 table 的公共键匹配。其中许多值都有合理的理由为空,但在某些环境中它们甚至不存在,这是我需要确定的问题,可能通过插入自定义字符串,例如"\\NULL///"...
我有一组预生产环境,其中每个环境在 table 中都有很多配置参数,我已经将它们提取到一个巨大的 table.
中我现在正在尝试编写一个 SQL 以在 2D-table 中呈现某些参数集(环境与参数 x-ref 值 table),以确定有问题的值,完全缺少一些参数。
SELECT x0.envName,
x1.param1,
x2.param2,
x3.param3
FROM ( ( (
(SELECT envName
FROM paramTable
GROUP BY envName) x0
LEFT JOIN
( SELECT envName,
parameterValue AS param1
FROM paramTable
WHERE parameterName='param1' ) x1 ON x1.envName = x0.envName )
LEFT JOIN
( SELECT envName,
parameterValue AS param2
FROM paramTable
WHERE parameterName='param2' ) x2 ON x2.envName = x0.envName )
LEFT JOIN
( SELECT envName,
parameterValue AS param3
FROM paramTable
WHERE parameterName='param3' ) x3 ON x3.envName = x0.envName)
如果我的参数表是这样的:
+ paramTable
=================================================
envName | paramName | paramValue |
-------------------------------------------------
env1 | param1 | abcdef |
env1 | param2 | 123456 |
env1 | param3 | A73BB2 |
env2 | param1 | klmnop |
env2 | param2 | 987654 |
env2 | param3 | |
env3 | param2 | uvwxyz |
然后,此查询的结果 table 将不会区分空字符串值(例如 env2 上的 param3)和不存在的值(例如 env3 中的 param1 和 param3):
+ ResultQueryResult
=================================================================
envName | param1 | param2 | param3 |
-----------------------------------------------------------------
env1 | abcdef | 123456 | A73BB2 |
env2 | klmnop | 987654 | |
env3 | | uvwxyz | |
我想以某种方式修改 SQL,以便结果查询会得到这样的结果:
+ PreferedQueryResult
=================================================================
envName | param1 | param2 | param3 |
-----------------------------------------------------------------
env1 | abcdef | 123456 | A73BB2 |
env2 | klmnop | 987654 | |
env3 | <<<!NULL!>>> | uvwxyz | <<<!NULL!>>> |
你可以简单地使用像 <<<!NULL!>>>
这样的特殊常量并更改:
select paramValue
来自
select nvl(paramValue,'<<<!NULL!>>>')
或添加一个布尔列(对于每个参数):
替换
select paramValue
来自
select
case when paramValue is null
then True
else False
end as isParamValueNull,
paramValue
在结果中包含来自内部 table 的 NOT NULL 字段。然后,当该字段为 NULL 时,您知道内部行不存在(与其 NULL-able 字段为 NULL 相反)。
当在必须为 NOT NULL 的主键上加入时,您可以使用其中一个 PK 字段(在您的情况下似乎是 envName
/paramName
)。否则,你可以 "invent" 你自己的非 NULL 字段,通过在子查询上加入:
...
LEFT JOIN (SELECT 1 inner_exists, <other fields> FROM inner ...) Q
ON ...
避免使用 "magic" 值,因为您永远不知道它们是否实际存在于真实数据中。或者,如果你走那条路,使用不太可能出现的东西,比如 GUID。
DECLARE @paramTable TABLE (envName varchar(15), parameterName varchar(15), parameterValue varchar(15) )
INSERT INTO @paramTable (envName, parameterName, parameterValue)
VALUES
('env1','param1','abcdef')
,('env1','param2','123456')
,('env1','param3','A73BB2')
,('env2','param1','klmnop')
,('env2','param2','987654')
,('env2','param3','' )
,('env3','param2','uvwxyz')
select x0.envName, ISNULL(x1.param1,'<<!NULL!>>') as param1, ISNULL(x2.param2,'<<!NULL!>>') as param2,ISNULL(x3.param3,'<<!NULL!>>') as param3
from
(
(
(
(select envName from @paramTable group by envName) x0
left join
(
select envName, parameterValue as param1 from @paramTable where parameterName='param1'
) x1
on x1.envName = x0.envName
)
left join
(
select envName, parameterValue as param2 from @paramTable where parameterName='param2'
) x2
on x2.envName = x0.envName
)
left join (
select envName, parameterValue as param3 from @paramTable where parameterName='param3'
) x3
on x3.envName = x0.envName
)
结果:
envName param1 param2 param3
--------------- --------------- --------------- ---------------
env1 abcdef 123456 A73BB2
env2 klmnop 987654
env3 <<!NULL!>> uvwxyz <<!NULL!>>
我试图重写您的查询:
SELECT x0.envName,
CASE WHEN x1.parameterName='param1' THEN x1.param1 ELSE '<<!NULL!>>' END AS param1,
CASE WHEN x1.parameterName='param2' THEN x1.param1 ELSE '<<!NULL!>>' END AS param2,
CASE WHEN x1.parameterName='param3' THEN x1.param1 ELSE '<<!NULL!>>' END AS param3
FROM (SELECT envName
FROM paramTable
GROUP BY envName) x0
LEFT JOIN paramTable x1
ON x1.envName = x0.envName