我试图解决以下SQL查询,它应该显示今年有更多问题的设备数据,而不是去年所有设备的平均问题数量和我;有点困惑。
到目前为止,我已经提出了这个问题:select e.equipment_id ,
e.equipment_name ,
e.equipment_serialnum ,
e.equipment_descrip
from equipment e ,
problems p
where e.equipment_id = p.equipment_id
and year( problem_date ) = year( getdate() )
group by e.equipment_id ,
e.equipment_name ,
e.equipment_serialnum ,
e.equipment_descrip
having count(p.problem_id) > ( select avg( pnumber )
from ( SELECT p1.problem_id ,
COUNT( p1.problem_id ) AS pnumber
FROM problems p1
JOIN equipment e1 ON e1.equipment_id = p1.equipment_id
and year( p1.problem_date ) = 2013
GROUP BY p1.problem_id
)
但它没有用。这是查询中涉及的表的结构
problems
(
problem_id integer not null identity(1,1)
equipment_id integer not null,
user_id integer not null,
problem_date datetime not null,
problem_descrip varchar(255)
)
equipment
(
equipment_id integer not null identity(1,1) ,
equipment_type_cod char(20) not null ,
equipment_bought datetime not null ,
equipment_available datetime ,
equipment_serialnum char(20) ,
equipment_name varchar(255) ,
equipment_descrip varchar(255)
)
感谢您提供的任何帮助。
答案 0 :(得分:1)
您的子选择需要表名
( select avg( pnumber )
from ( SELECT p1.problem_id ,
COUNT( p1.problem_id ) AS pnumber
FROM problems p1
JOIN equipment e1 ON e1.equipment_id = p1.equipment_id
and year( p1.problem_date ) = 2013
GROUP BY p1.problem_id
) x
)
答案 1 :(得分:0)
首先,让我们创建我们的架构:
create table dbo.equipment
(
equipment_id integer not null identity(1,1) primary key clustered ,
equipment_type_cod char(20) not null ,
equipment_bought datetime not null ,
equipment_available datetime ,
equipment_serialnum char(20) ,
equipment_name varchar(255) ,
equipment_descrip varchar(255) ,
)
go
create table dbo.problems
(
problem_id integer not null identity(1,1) primary key clustered ,
equipment_id integer not null foreign key references dbo.equipment( equipment_id ) ,
user_id integer not null ,
problem_date datetime not null ,
problem_descrip varchar(255) ,
)
go
将我们的问题分解为更小的离散块通常很有帮助。 SQL Server的with
子句在这里很有用,因为它提供了一种定义名称虚拟表的便捷方法:
with
--
-- a 1-row table containing the starting date for the previous, current and next years
--
year_start as (
select prev = convert(date,datename(year,dateadd(year, -1 , current_timestamp))) ,
curr = convert(date,datename(year,dateadd(year, 0 , current_timestamp))) ,
next = convert(date,datename(year,dateadd(year, +1 , current_timestamp)))
) ,
--
-- the count of problems per unit over the previous year. This
-- uses a left join to include those pieces of equipment that had no problems.
-- Depending on you requirement, you might want to change that to an inner join.
--
prev_year_problems as (
select equipment_id = e.equipment_id ,
problem_cnt = coalesce( p.problems , 0 )
from dbo.equipment e
left join ( select equipment_id = p.equipment_id ,
problems = count(*)
from dbo.problems p
cross join year_start y
where p.problem_date >= y.prev
and p.problem_date < y.curr
group by p.equipment_id
) p on p.equipment_id = e.equipment_id
) ,
--
-- the count of problems per unit in the current year, up to the current date.
-- This is essentially identical to the previous CTE, with the exception of
-- the boundaries of the desired date range.
--
curr_year_problems as (
select equipment_id = e.equipment_id ,
problem_cnt = coalesce( p.problems , 0 )
from dbo.equipment e
left join ( select equipment_id = p.equipment_id ,
problems = count(*)
from dbo.problems p
cross join year_start y
where p.problem_date >= y.curr
and p.problem_date < y.next
group by p.equipment_id
) p on p.equipment_id = e.equipment_id
) ,
--
-- Here, we roll the previous year's problem counts up and summarize them into
-- a single row table containing the mean number of problems per unit over the year.
--
previous_year_summary as (
select mean_problems_per_unit = avg( t.problem_cnt )
from prev_year_problems t
)
--
-- Finally, we select the rows from the equipment table that meet the defined
-- criteria
--
select e.* ,
curr_year_problems_to_date = cyp.problem_cnt ,
prev_year_mean_problems_per_unit = ps.mean_problems_per_unit
from dbo.equipment e
join curr_year_problems cyp on cyp.equipment_id = e.equipment_id
join previous_year_summary ps on cyp.problem_cnt > ps.mean_problems_per_unit