Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Null和notnull值进行Sql选择_Sql_Select_Null_Oracle12c_Exists - Fatal编程技术网

使用Null和notnull值进行Sql选择

使用Null和notnull值进行Sql选择,sql,select,null,oracle12c,exists,Sql,Select,Null,Oracle12c,Exists,我有一张像下面这样的桌子 我想选择语言不为null的规范id。但是当一个spec_id除了null之外没有其他值时,我想选择这个spec_id也有null值。 例如,规范id“170470”的语言为“EN”。我只想为这个spec_id选择语言为notnull的行,spec_id“170464”只有null值。所以我也想选择那一行 我尝试了下面的查询,但它只选择语言中NOTNULL的情况 SELECT * from temp_value w1 where w1.NAC_ID =

我有一张像下面这样的桌子

我想选择语言不为null的规范id。但是当一个spec_id除了null之外没有其他值时,我想选择这个spec_id也有null值。 例如,规范id“170470”的语言为“EN”。我只想为这个spec_id选择语言为notnull的行,spec_id“170464”只有null值。所以我也想选择那一行

我尝试了下面的查询,但它只选择语言中NOTNULL的情况

   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);

我认为我们可以通过使用
行数
来简化这个过程:

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
last。这意味着,对于每组
spec\u id
记录,非
NULL
语言值将浮到顶部(如果存在)。只有当给定的
spec\u 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
            )
         );

还是我遗漏了什么?

您也可以只使用相关子查询:在子查询中,您引用了主查询的表别名

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));

嗨,我试过了。这适用于这种情况,但如果一个规范id有更多的语言,例如,对于规范id 170470,如果有两种语言,如EN和DE,则只选择第1行值。@newintodev确定,请检查我刚才添加到答案中的第二个查询。