Sql select 具有 Null 和 Not Null 值
Sql select with Null and Not Null values
我有一个 table 如下所示。
我想 select spec_id with language is not null。但是当 spec_id 除了 null 之外没有其他值时,我想 select 那个 spec_id 也具有 null 值。
例如。 Spec_id“170470”的语言为 'EN'。我想 select 只有语言行对于此 spec_id 不为空。而 spec_id '170464' 只有 Null 值。所以我也想 select 那一行。
我已尝试使用以下查询,但它 select 仅是语言中 NOT NULL 的情况。
SELECT * from temp_value w1
where w1.NAC_ID = 2453
and w1.language is not null
or (w1.language is null and not exists (select spec_id from temp_value w2
where w2.nac_id = 2453
and spec_id in (select spec_id from temp_value
where nac_id = 2453 and language is not null))
and w1.nac_id = 2453);
我认为我们实际上可以通过使用 ROW_NUMBER
:
来简化它
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY spec_id ORDER BY language) rn
FROM temp_value t
)
SELECT language, value, value_id, spec_id, language_id, nac_id
FROM cte
WHERE rn = 1;
这应该可行,因为 Oracle 默认将 NULL
排在最后。这意味着,对于每组 spec_id
记录,非 NULL
语言值将浮动到顶部(如果存在)。仅当给定的 spec_id
组没有非 NULL
语言记录时,才会选择 NULL
记录。
编辑:
为了解决可能有两个或多个非NULL
语言记录的问题,按照之前的逻辑只保留一个NULL
应该没有非NULL
记录,我们可以试试:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY spec_id ORDER BY language) rn
FROM temp_value t
)
SELECT language, value, value_id, spec_id, language_id, nac_id
FROM cte
WHERE language IS NOT NULL OR (rn = 1 AND language IS NULL);
你试过了吗:
SELECT * from temp_value w1
where w1.NAC_ID = 2453
and w1.language is not null
or (w1.language is null and not exists
(select spec_id from temp_value w2
where w2.nac_id = 2453
and w2.spec_id=w1.spec_id
and language is not null
)
);
还是我遗漏了什么?
您也可以只使用相关子查询:在子查询中您引用主查询的 table 别名。
select * from temp_value t
where language is not null
or language is null and not exists (select 'x'
from temp_value
where spec_id = t.spec_id
and nac_id = t.nac_id
and (language is not null
or value is not null
or language_id is not null));
我有一个 table 如下所示。
我想 select spec_id with language is not null。但是当 spec_id 除了 null 之外没有其他值时,我想 select 那个 spec_id 也具有 null 值。 例如。 Spec_id“170470”的语言为 'EN'。我想 select 只有语言行对于此 spec_id 不为空。而 spec_id '170464' 只有 Null 值。所以我也想 select 那一行。
我已尝试使用以下查询,但它 select 仅是语言中 NOT NULL 的情况。
SELECT * from temp_value w1
where w1.NAC_ID = 2453
and w1.language is not null
or (w1.language is null and not exists (select spec_id from temp_value w2
where w2.nac_id = 2453
and spec_id in (select spec_id from temp_value
where nac_id = 2453 and language is not null))
and w1.nac_id = 2453);
我认为我们实际上可以通过使用 ROW_NUMBER
:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY spec_id ORDER BY language) rn
FROM temp_value t
)
SELECT language, value, value_id, spec_id, language_id, nac_id
FROM cte
WHERE rn = 1;
这应该可行,因为 Oracle 默认将 NULL
排在最后。这意味着,对于每组 spec_id
记录,非 NULL
语言值将浮动到顶部(如果存在)。仅当给定的 spec_id
组没有非 NULL
语言记录时,才会选择 NULL
记录。
编辑:
为了解决可能有两个或多个非NULL
语言记录的问题,按照之前的逻辑只保留一个NULL
应该没有非NULL
记录,我们可以试试:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY spec_id ORDER BY language) rn
FROM temp_value t
)
SELECT language, value, value_id, spec_id, language_id, nac_id
FROM cte
WHERE language IS NOT NULL OR (rn = 1 AND language IS NULL);
你试过了吗:
SELECT * from temp_value w1
where w1.NAC_ID = 2453
and w1.language is not null
or (w1.language is null and not exists
(select spec_id from temp_value w2
where w2.nac_id = 2453
and w2.spec_id=w1.spec_id
and language is not null
)
);
还是我遗漏了什么?
您也可以只使用相关子查询:在子查询中您引用主查询的 table 别名。
select * from temp_value t
where language is not null
or language is null and not exists (select 'x'
from temp_value
where spec_id = t.spec_id
and nac_id = t.nac_id
and (language is not null
or value is not null
or language_id is not null));