正如标题所说,查询需要组合多个选择查询。问题如下:
显示员工总数,以及1995,1996,1997,1998中雇用的员工总数。
我的查询:
select (select count(*) from employees) as "Total",
(select count(*) from employees where hire_date between 'JAN-1-0095' and 'DEC-1-0095')as "1995",
(select count(*) from employees where hire_date between 'JAN-1-0096' and 'DEC-1-0096') as "1996",
(select count(*) from employees where hire_date between 'JAN-1-0097' and 'DEC-1-0097') as "1997",
(select count(*) from employees where hire_date between 'JAN-1-0098' and 'DEC-1-0098') as "1998"
from employees
但问题是,只返回单个记录,而是对表中的所有记录执行此查询,从而产生以下输出:
答案 0 :(得分:3)
您可以使用条件计数:
select count(*) as total_count,
count(case when extract(year from hire_date) = 1995 then 1 end) as "1995",
count(case when extract(year from hire_date) = 1996 then 1 end) as "1996",
count(case when extract(year from hire_date) = 1997 then 1 end) as "1997",
count(case when extract(year from hire_date) = 1998 then 1 end) as "1997",
from employees;
这利用了聚合函数忽略NULL值这一事实,因此count()
只计算case
表达式返回非空值的那些行。
您的查询为employees表中的每一行返回一行,因为您不应用任何分组。每个select都是一个标量子选择,可以为employees
表中的每一行执行。
如果您将最终的from employees
替换为from dual
,可以使其仅返回一行 - 但您仍然会计算每个子行中的所有行-select。
您还应该像您一样避免隐式数据类型转换。 'JAN-1-0095'
是一个字符串,根据您的NLS设置隐式转换为date
。如果从我的计算机执行,您的查询将无法运行(因为NLS设置不同)。
当你正在寻找一整年时,只需比较年份就可以更短,更容易理解(至少在我看来)。
另一个选择是使用正确的日期文字,例如使用Oracle的where hire_date between DATE '1995-01-01' and DATE '1995-12-31'
函数to_date()
或更加冗长:where hire_date between to_date('1995-01-01', 'yyyy-mm-dd') and to_date('1995-12-31', 'yyyy-mm-dd')
答案 1 :(得分:0)
假设这些年份确实是你想要的,你的查询的问题是你从employees
中选择,所以你得到每一行。你可以使用:
select (select count(*) from employees) as "Total",
(select count(*) from employees where hire_date between 'JAN-1-0095' and 'DEC-1-0095')as "1995",
(select count(*) from employees where hire_date between 'JAN-1-0096' and 'DEC-1-0096') as "1996",
(select count(*) from employees where hire_date between 'JAN-1-0097' and 'DEC-1-0097') as "1997",
(select count(*) from employees where hire_date between 'JAN-1-0098' and 'DEC-1-0098') as "1998"
from dual;
我会使用date '1998-01-01'
作为日期常量。
但是,我更喜欢@ a_horse_with_no_name的解决方案。
答案 2 :(得分:0)
您应该避免使用大量子查询。你应该试试这个:
SQL Server:
select distinct
a.id_clients,a.name,
case when b.id_clients_action=2 then b.date_action else null end as date
from clients a
left join clients_action b on a.id_user_created=b.id_user_created
在ORACLE中
SELECT count(*) as Total, hire_date
FROM employees
WHERE year(hire_date) IN ('1995','1996','1997','1998')
GROUP BY hire_date WITH CUBE
除了GROUP BY生成的小计之外,CUBE扩展还会为每个hire_date生成小计。