Sql 如何获取具有空值和空值的行

Sql 如何获取具有空值和空值的行,sql,sql-server,Sql,Sql Server,面试官问了我以下问题: 考虑下表: tpid data 100 1 100 2 100 NULL 101 6 101 5 101 NULL 102 NULL 103 9 103 65 104 NULL .. .. 如果tpid有任何数据,则显示数据且不为空值 但是,如果tpid仅为null,则仅针对该id显示null 结果集应如下所示: tpid data 100 1 100 2 101 6 101 5 102 NULL 103 9 103 65 104 NULL 我编写了以下查询,但没有给

面试官问了我以下问题:

考虑下表:

tpid data
100 1
100 2
100 NULL
101 6
101 5
101 NULL
102 NULL
103 9
103 65
104 NULL
..
..
如果
tpid
有任何数据,则显示数据且不为空值 但是,如果
tpid
仅为null,则仅针对该id显示null

结果集应如下所示:

tpid data
100 1
100 2
101 6
101 5
102 NULL
103 9
103 65
104 NULL
我编写了以下查询,但没有给出所需的结果:

;with cte as
(select tpid,count(data) as num from a group by TPID)

 select a.TPID,
 (case when cte.num=0 then NULL else a.DATA end)col
 from cte
join A on a.TPID=cte.TPID

您可以使用窗口函数来获取所需内容:

SELECT tpid, data
FROM (
  SELECT tpid, data,
         COUNT(*) OVER (PARTITION BY tpid) AS cnt,
         COUNT(CASE WHEN [data] IS NULL THEN 1 END) 
         OVER (PARTITION BY tpid) AS cntNulls
  FROM mytable) AS t
  WHERE (data IS NOT NULL) OR (cnt = cntNulls)
NULL
值会被过滤掉,除非
tpid
切片中除了
NULL
值之外什么都没有

或者,您可以使用以下查询:

SELECT t1.tpid, t1.data
FROM mytable AS t1
LEFT JOIN (
  SELECT tpid
  FROM mytable
  GROUP BY tpid
  HAVING COUNT(*) = COUNT(CASE WHEN data IS NULL THEN 1 END)
) AS t2 ON t1.tpid = t2.tpid
WHERE (t1.data IS NOT NULL) OR (t2.tpid IS NOT NULL)

您可以使用窗口函数来获取所需内容:

SELECT tpid, data
FROM (
  SELECT tpid, data,
         COUNT(*) OVER (PARTITION BY tpid) AS cnt,
         COUNT(CASE WHEN [data] IS NULL THEN 1 END) 
         OVER (PARTITION BY tpid) AS cntNulls
  FROM mytable) AS t
  WHERE (data IS NOT NULL) OR (cnt = cntNulls)
NULL
值会被过滤掉,除非
tpid
切片中除了
NULL
值之外什么都没有

或者,您可以使用以下查询:

SELECT t1.tpid, t1.data
FROM mytable AS t1
LEFT JOIN (
  SELECT tpid
  FROM mytable
  GROUP BY tpid
  HAVING COUNT(*) = COUNT(CASE WHEN data IS NULL THEN 1 END)
) AS t2 ON t1.tpid = t2.tpid
WHERE (t1.data IS NOT NULL) OR (t2.tpid IS NOT NULL)

答复:

答复:


这看起来像是我答案的复制/粘贴这看起来像是我答案的复制/粘贴
select tpid,data from (SELECT tpid, data,
         COUNT(*) OVER (PARTITION BY tpid) AS cnt,
         COUNT(CASE WHEN [data] IS NULL THEN 1 END) 
         OVER (PARTITION BY tpid) AS cntNulls
  FROM mytable) t
  where t.cntNulls = t.cnt or data is not null