我有一个包含标题和值的表。
对于不同的标题,我想检索所有非空值,除非该标题仅具有NULL值。
我的桌子的样品看起来像这样:
Title Value
---------------
ex1 8
ex1 9
ex1 NULL
ex2 8
ex2 NULL
ex3 NULL
在此示例中,我希望我的期望输出如下所示:
Libelle TPO_code
--------------------
ex1 8
ex1 9
ex2 8
ex3 NULL
我可以通过以下请求来获取除NULL值以外的所有值,但是在标题只有NULL值的情况下我被阻止了:
select distinct Title, Value
from mytable
where Value is not null
答案 0 :(得分:4)
您可以使用“不存在”:
SELECT DISTINCT T.Title
, T.Value
FROM mytable T
WHERE T.Value IS NOT NULL
OR NOT EXISTS (
SELECT NULL
FROM mytable T2
WHERE T2.Value IS NOT NULL
AND T2.Title = T1.Title
)
答案 1 :(得分:2)
如果需要,您可以避免使用联合并尝试:
DECLARE @myTable AS TABLE (Title CHAR(4) NOT NULL, Value INT NULL);
INSERT INTO @myTable (Title, Value)
VALUES ('ex1', 8)
, ('ex1', 9)
, ('ex1', NULL)
, ('ex2', 8)
, ('ex2', NULL)
, ('ex3', NULL);
SELECT DISTINCT
T1.Title
, T2.Value
FROM @myTable T1
LEFT JOIN @myTable T2 ON T2.Title = T1.Title
AND T2.Value IS NOT NULL;
我建议您针对实际数据的形状尝试所有这些选项,以找到最有效的版本。也值得花一些时间检查索引等以使其更快。
答案 2 :(得分:1)
另一种选择是使用联合和子查询
declare @t table (Title varchar(10), Value int)
insert into @t (Title, Value)
values ('ex1', 8), ('ex1', 9), ('ex1', null), ('ex2', 8), ('ex2', null), ('ex3', null)
-- first get all rows with Value different from null
select t.Title,
t.Value
from @t t
where t.Value is not null
union
-- now also get all rows with just one row and where that row has null in value
select t.Title,
t.Value
from @t t
where t.Title in ( select t2.title from @t t2 group by t2.Title having count(t2.Title) = 1 )
and t.Value is null
这将返回此结果
Title Value
----- -----
ex1 8
ex1 9
ex2 8
ex3 null
答案 3 :(得分:1)
其他选项:
DECLARE @myTable AS TABLE (Title CHAR(4) NOT NULL, Value INT NULL);
INSERT INTO @myTable (Title, Value)
VALUES ('ex1', 8)
, ('ex1', 9)
, ('ex1', NULL)
, ('ex2', 8)
, ('ex2', NULL)
, ('ex3', NULL);
-- Original
SELECT DISTINCT
T1.Title
, T2.Value
FROM @myTable T1
LEFT JOIN @myTable T2 ON T2.Title = T1.Title
AND T2.Value IS NOT NULL;
-- Common Table Expression example
WITH cte AS
(SELECT *
, ROW_NUMBER() OVER (PARTITION BY Title
ORDER BY Value DESC) RN
FROM @myTable)
SELECT cte.Title
, cte.Value
FROM cte
WHERE RN = 1
OR cte.Value IS NOT NULL
如果您遍历公用表表达式并分配行号,则可以确保每个“标题”至少有一行,而不会出现多个表。如果您并排运行两个执行计划,那么我会发现在联接上节省了CTE版本。这将取决于要输入的数据量,尽管排序可能会比连接昂贵,尽管连接版本需要针对不同的数据进行排序。
让他们尝试实际数据并获得一些时间安排。让我知道是否有帮助。
答案 4 :(得分:0)
尝试一下
;WITH CTE (Title, Value)
AS
(
SELECT 'ex1', 8 UNION ALL
SELECT 'ex1', 9 UNION ALL
SELECT 'ex1', NULL UNION ALL
SELECT 'ex2', 8 UNION ALL
SELECT 'ex2', NULL UNION ALL
SELECT 'ex3', NULL
)
,CTe2
AS
(
SELECT Title, Value, COUNT(Title)OVER(PARTITION BY Title ORDER BY Title) cnt
FROM CTE
)
SELECT Title,
Value
FROM CTe2 WHERE ISNULL(Value,1) <> 1
UNION ALL
SELECT Title,
Value
FROM CTe2 WHERE cnt =1
结果
Title Value
-------------
ex1 8
ex1 9
ex2 8
ex3 NULL
答案 5 :(得分:0)
我可以为您的问题建议以下解决方案,
select title,value from mytable where id is not null
union
select title,value from (
select title,value, dense_rank() over (partition by title order by value) rank from mytable)
where rank=1
答案 6 :(得分:0)
SELECT
DISTINCT a.Title,
b.Value
FROM
mytable a
LEFT JOIN
mytable b
ON
a.Title = b.Title
AND
b.Value IS NOT NULL;