Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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 使用Group By汇总表中的空值_Sql_Sqlite_Group By - Fatal编程技术网

Sql 使用Group By汇总表中的空值

Sql 使用Group By汇总表中的空值,sql,sqlite,group-by,Sql,Sqlite,Group By,我有两张桌子: 人员(身份证、姓名) 运动(个人识别码,运动) 问题是:Sport可能有空值。如果是这样的话,那么如果我按ID分组,运动应该是空的 SELECT p.ID, p.Name, s.Sport FROM Person p INNER JOIN Sports s ON p.ID=s.person_id GROUP BY p.ID 如果不按表分组,则如下所示: p.ID p.Name s.Sport 1 tom soccer 1 tom NULL 2

我有两张桌子:

  • 人员(身份证、姓名)
  • 运动(个人识别码,运动)
问题是:Sport可能有空值。如果是这样的话,那么如果我按ID分组,运动应该是空的

SELECT p.ID, p.Name, s.Sport
FROM Person p
INNER JOIN Sports s ON p.ID=s.person_id
GROUP BY p.ID
如果不按表分组,则如下所示:

p.ID p.Name s.Sport
1    tom    soccer
1    tom    NULL
2    lisa   golf
2    lisa   soccer
3    tim    golf
3    tim    NULL
我现在想要的是:

1 tom NULL
2 lisa golf
3 tim NULL
但我得到的是:

1 tom soccer
2 lisa golf
3 tim golf

我尝试过子选择和ifs,但没有任何效果。提前谢谢

这里有一个查询,可以生成您的预期结果集,尽管@jarlh已经指出,不清楚为什么Lisa应该打高尔夫而不是足球

SELECT
    p.ID,
    p.Name,
    CASE WHEN COUNT(CASE WHEN s.Sport IS NULL THEN 1 END) > 0
         THEN NULL ELSE MIN(s.Sport) END AS Sport
FROM Person p
INNER JOIN Sports s
    ON p.ID = s.person_id
GROUP BY
    p.ID,
    p.name;

请注意,我同时按
ID
name
进行分组,这在许多数据库上都是必需的(虽然可能不是SQLite)。

不能使用aggreagtion函数作为MIN()来管理空值 但是你可以试试

SELECT p.ID, p.Name, min(ifnull(s.Sport,'')) 
FROM Person p 
INNER JOIN Sports s ON p.ID=s.person_id 
GROUP BY p.ID, p.name

假设您使用的SQLLite版本支持
行号()
,请尝试以下操作,如果您
订购s.sport ASC
,则可以将
行号设置为1,然后为每个类别选择第一行。如果为空,则应通过此查询定位在每个类别的顶行。您不需要使用
分组依据

;with cte as (
select p.ID, p.Name, s.Sport, 
       ROW_NUMBER() OVER (PARTITION BY p.ID ORDER BY s.Sport ASC) AS rn
FROM Person p INNER JOIN Sports s ON p.ID=s.person_id
)
select *
from cte
where rn=1

可以使用相关子查询执行此操作,避免外部查询中的
join

select p.*,
       (select s.sport
        from sports s
        where s.personId = p.id
        order by (s.sport is null) desc, s.sport asc
       ) as min_sport
from person p;
在某些情况下,这可能是有用的。在
运动(personid,sport)
上有一个索引,它可能比
组快
,这取决于数据(很多人,每人很少运动)


此外,这与您的查询略有不同,因为它返回所有人,即使是没有运动的人。

为什么Lisa应该打高尔夫而不是足球?如果我运行此功能,如果有多人(在我的系统上),Group by函数总是选择第一行。但这并不重要。我只需要tim和tom是select列表中的空用例表达式,就可以进行条件聚合。如果列有空值,请记住count(*)count(column)。@stuckon在这里,为什么不将sport为空的
添加到查询中呢?如果我只添加为空,它会删除lisa条目,我需要这个条目。当然,这是假设OP版本的SQLite支持
行数
。这是可行的!这是非常有用的表达式计数(Case…)。谢谢。