对两个SQL表进行分组和求和,并替换缺少的值
我有下表“人员”: 另一个表格“金额”: 其中persons.id对应于amounts.customerid 如何返回一个sql查询,该查询返回1月份每人生成的金额,空customerid的名称为“未知”对两个SQL表进行分组和求和,并替换缺少的值,sql,sqlite,join,group-by,Sql,Sqlite,Join,Group By,我有下表“人员”: 另一个表格“金额”: 其中persons.id对应于amounts.customerid 如何返回一个sql查询,该查询返回1月份每人生成的金额,空customerid的名称为“未知” 如果没有左连接,可以分两步完成。首先加入并聚合已知人员。然后加上未知数 select p.name, sum(a.amount) from amounts a join persons p on a.customerid = p.id where a.month = 'Jan' group b
如果没有左连接,可以分两步完成。首先加入并聚合已知人员。然后加上未知数
select p.name, sum(a.amount)
from amounts a
join persons p on a.customerid = p.id
where a.month = 'Jan'
group by p.name
union all
select 'Unknown', sum(amount)
from amounts
where a.month = 'Jan' and customerid is null
我相信一个左连接和
COALESCE()
会在这里起作用:
SELECT COAELSCE(persons.name, 'Unknown') as personname, sum(amount) sumamount
FROM amounts
LEFT OUTER JOIN person ON amounts.customerid = persons.id
GROUP BY COALESCE(persons.name, 'Unknown')
WHERE month = 'Jan';
您的需求可以通过
完全外部联接来解决,但SQLite不支持它。
因此,您可以对表persons
使用UNION ALL
来包含id为null的行,然后是左连接
:
select p.name, coalesce(sum(a.value), 0) value
from (select * from persons union all select null, 'Unknown') p
left join (select * from amounts where month = 'Jan') a
on (p.id = a.customerid) or (p.id is null and a.customerid is null)
where p.id is not null or a.value is not null
group by p.id, p.name
order by p.name is null, p.name
条件:
where p.id is not null or a.value is not null
确保如果没有customerid
s且null
为空,则结果中将不会有名为'Unknown'
且value=0的行
请参阅。
结果:
从技术上讲,您需要的是表之间的完全联接。遗憾的是,SQLite不支持完全连接
有不同的方法来模拟解决方案。然而,对于这个特殊的情况,我认为使用左连接
来获取所有的人就足够了。然后UNION ALL
引入未知:
select p.name, coalesce(sum(a.value), 0) value
from persons p left join
amounts a
on a.customerid = p.id and
a.month = 'Jan'
group by p.name
union all
select 'Unknown', sum(a.value)
from amounts a
where a.customerid is null;
他是一把小提琴
第一个查询使用left join
将所有客户(即使是那些没有金额的客户)带入。第二个是“unknown”。名称和值是糟糕的表名。Persons(或者customers)是更好的表名。此外,value是一个糟糕的列名。什么值?做一个外部连接。group by.edited表格名称。@jarlh我正在尝试在sqlite上使用此示例,其中不支持外部联接。还有其他方法吗?您应该提及/标记您使用的SQL方言。如果是Oracle,这里有一个指针:
select p.name, coalesce(sum(a.value), 0) value
from (select * from persons union all select null, 'Unknown') p
left join (select * from amounts where month = 'Jan') a
on (p.id = a.customerid) or (p.id is null and a.customerid is null)
where p.id is not null or a.value is not null
group by p.id, p.name
order by p.name is null, p.name
where p.id is not null or a.value is not null
| name | value |
| ------- | ----- |
| Adam | 1700 |
| Nick | 700 |
| John | 0 |
| Unknown | 210 |
select p.name, coalesce(sum(a.value), 0) value
from persons p left join
amounts a
on a.customerid = p.id and
a.month = 'Jan'
group by p.name
union all
select 'Unknown', sum(a.value)
from amounts a
where a.customerid is null;