Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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
Sql 如果有多个值,则选择列不为null的行;如果有1个值,则选择列不为null的行_Sql_Sql Server - Fatal编程技术网

Sql 如果有多个值,则选择列不为null的行;如果有1个值,则选择列不为null的行

Sql 如果有多个值,则选择列不为null的行;如果有1个值,则选择列不为null的行,sql,sql-server,Sql,Sql Server,我有一个包含标题和值的表 对于不同的标题,我希望检索所有非空值,除非该标题只有空值 我的表格示例如下所示: Title Value --------------- ex1 8 ex1 9 ex1 NULL ex2 8 ex2 NULL ex3 NULL Libelle TPO_code -------------------- ex1 8 ex1 9 ex2

我有一个包含标题和值的表

对于不同的标题,我希望检索所有非空值,除非该标题只有空值

我的表格示例如下所示:

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
在本例中,我希望所需的输出如下所示:

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
我可以通过以下请求检索除空值以外的所有值,但由于标题只有空值,我被阻止:

select distinct Title, Value 
from mytable
where Value is not null

您可以使用不存在的文件:

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
                    )

您可以使用不存在的文件:

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
                    )

另一种选择是使用联合和子查询

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    

另一种选择是使用联合和子查询

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    
试试这个

;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
试试这个

;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

如果需要,可以避免使用联合体,并尝试以下方法:

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;

我建议您根据实际数据的形状尝试所有这些选项,以找到最有效的版本。也值得花一些时间检查索引等,以使这些更快

如果需要,可以避免使用联合体,并尝试以下方法:

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;

我建议您根据实际数据的形状尝试所有这些选项,以找到最有效的版本。也值得花一些时间检查索引等,以使这些更快

我可以为您的问题提出以下解决方案

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

我可以为您的问题提出以下解决方案

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
其他选择:

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版本在连接上的保存。尽管排序可能比联接更昂贵,但是联接版本需要对distinct进行排序,这将取决于传入的数据量

让他们尝试一下真实的数据,并获得一些时间安排。如果有帮助,请告诉我。

其他选项:

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
SELECT      
    DISTINCT a.Title,           
             b.Value   
FROM      
    mytable a   
LEFT JOIN 
    mytable b 
ON  
    a.Title = b.Title 
AND  
    b.Value IS NOT NULL;
如果运行公共表表达式并指定行号,则可以确保每个“标题”至少有一行,而不会出现多个表命中。如果你同时运行两个执行计划,我会看到cte版本在连接上的保存。尽管排序可能比联接更昂贵,但是联接版本需要对distinct进行排序,这将取决于传入的数据量


让他们尝试一下真实的数据,并获得一些时间安排。如果这有帮助,请告诉我。

很好的发现,我没有想到使用联接来实现此目的。通常这是我第一次尝试,因为它通常是最有效的+1@GuidoG-谢谢。这只是另一种选择。在不知道数据/索引等形状的情况下,总是要尝试一下,看看什么是最快的。我试图想出一种方法来做到这一点,而不必两次击中表-我将在一分钟后发布我的另一个选项查找,我没有想到使用连接。通常这是我第一次尝试,因为它通常是最有效的+1@GuidoG-谢谢。这只是另一种选择。在不知道数据/索引等形状的情况下,总是要尝试一下,看看什么是最快的。我在想一种不必两次点击表格的方法-我会在一分钟内发布我的另一个选项在我的数据上使用这个选项更快(3分钟10秒),尽管它只给我排名1。我将其调整为所有等级,如果标题的等级>2,则除空等级外。谢谢你的时间!哎呀,我的代码漏掉了底线。再来一次,看看这与你所调整的相比如何。能够从部分答案中得出解决方案通常更有用,因为这表明您已经理解了。在我的数据中,使用此选项更快(3分钟约10秒),尽管它只给我排名1。我将其调整为所有等级,如果标题的等级>2,则除空等级外。谢谢你的时间!哎呀,我的代码漏掉了底线。再来一次,看看这与你所调整的相比如何。能够从部分答案中找出答案通常更有用,因为这表明你已经理解了。
SELECT      
    DISTINCT a.Title,           
             b.Value   
FROM      
    mytable a   
LEFT JOIN 
    mytable b 
ON  
    a.Title = b.Title 
AND  
    b.Value IS NOT NULL;