选择列表中的错误无效,因为它不包含在聚合函数或GROUP BY子句中

时间:2014-08-04 18:15:13

标签: sql-server

我有4张桌子:

tblDiver:
diver_number int  primary key,
first_name char
last_name char

tblDiving:
diving_number int primary key,
date_of_diving date,
guide(equals to diver_number. a diver can be a guide if he authorized for that)

tblAuthorized:
diver_number,
level_name,
authorization_date

tblParticipate_in:
diver_number
diving_number

我想获得去年没有获得授权并且去年没有参加潜水的所有潜水员(包括导游)的清单(不作为向导而不是作为潜水员) 。我还想展示他们的潜水次数(所有时间。作为导游和潜水员),以及他们上次潜水的日期。如果潜水员作为潜水员参加,他将在表tblParticipate_in。如果他参与其中,那么他将作为“指南”参与其中。潜水员可以获得许多级别的授权,而不仅仅是指南。

我试过了:

SELECT tblDiver.diver_number,  tblDiver.first_name,tblDiver.last_name,
(select count(*) from tblDiver where tblDiver.diver_number=tblParticipate_in.diving_number  or     tblDiver.diver_number=tblDiving.guide) as Divings_in_past_year,
 max(tblDiving.date_of_diving) as last_Diving
FROM tblDiver, tblDiving,tblAuthorized,tblParticipate_in
WHERE (tblDiver.diver_number not IN((
SELECT tblDiver.diver_number
from tblParticipate_in
where(tblDiving.date_of_diving <= DATEADD(year,-1, GETDATE()) and
tblAuthorized.authorization_date <= DATEADD(year,-1, GETDATE()))

union

select tblDiver.diver_number
from tblDiving
where(tblDiver.diver_number=tblDiving.guide and
tblDiving.date_of_diving <= DATEADD(year,-1, GETDATE())
or tblAuthorized.authorization_date <= DATEADD(year,-1, GETDATE())))))

group by tblDiver.diver_number,  tblDiver.first_name,tblDiver.last_name

我收到了这个错误。 我确定我做的不是最好的方式(这是我的第一次)。 有人可以请我指点解决方案吗?

泰!

2 个答案:

答案 0 :(得分:1)

您的问题是您不能使用子查询来获取Divings_in_past_year,您必须使用聚合函数。您可以尝试使用以下内容替换子查询:

SUM(CASE 
  WHEN tblDiver.diver_number=tblParticipate_in.diving_number  or tblDiver.diver_number=tblDiving.guide THEN 1
  ELSE 0 
END) as Divings_in_past_year,

答案 1 :(得分:1)

这是我对它的看法,但它变得丑陋,我确信有一种更简单的方法......

(编辑)我的查询中有一些拼写错误,现在修复了

SELECT d.diver_number, d.first_name, d.last_name,
    SUM(s.dive_count) as all_time_total_dives,
    SUM(s.dives_in_last_year) as total_dives_in_last_year,
    MAX(s.most_recent_dive) as last_Dive, 
    t.most_recent_authorization
FROM tblDiver d 
    left join (
        select d1.diver_number, COUNT(*) dive_count, MAX(v1.date_of_diving) most_recent_dive, -- count and date as participant
            SUM(case when v1.date_of_diving >= DATEADD(year,-1,getdate()) then 1 else 0 end) dives_in_last_year
        from tblDiver d1
        join tblParticipate_in p1 on p1.diver_number = d1.diver_number
        join tblDiving v1 on v1.diving_number = p1.diving_number
        group by d1.diver_number
        union
        select d2.diver_number, COUNT(*) dive_count, MAX(v2.date_of_diving) most_recent_dive, -- count and date as guide
            SUM(case when v2.date_of_diving >= DATEADD(year,-1,getdate()) then 1 else 0 end) dives_in_last_year
        from tblDiver d2
        join tblDiving v2 on v2.guide = d2.diver_number
        group by d2.diver_number
    ) s on s.diver_number = d.diver_number
    left join (
        select d3.diver_number, MAX(authorization_date) most_recent_authorization
        from tblDiver d3
        join tblAuthorized a on a.diver_number = d3.diver_number
        group by d3.diver_number
    ) t on t.diver_number = d.diver_number
where t.most_recent_authorization is null or t.most_recent_authorization < DATEADD(year,-1,getdate()) -- no authorization in last year, or potentially no authorization
group by d.diver_number, d.first_name, d.last_name, t.most_recent_authorization
having MAX(s.most_recent_dive) is null or MAX(s.most_recent_dive) < DATEADD(year,-1,getdate()) -- no dives in last year or potentially ever

(最近评论后的新编辑)

SELECT tblDiver.diver_number, tblDiver.first_name, tblDiver.last_name,      
    count(distinct tblDiving.diving_number) as number_of_divins,     
    max(tblDiving.date_of_diving) as last_Diving   
FROM tblDiver 
    inner join tblParticipate_in on tblDiver.diver_number=tblParticipate_in.diver_number 
    inner join tblAuthorized on tblParticipate_in.diver_number=tblAuthorized.diver_number 
    inner join tblDiving on tblDiving.diving_number = tblParticipate_in.diving_number
WHERE tblAuthorized.authorization_date <= DATEADD(year,-1, GETDATE())
group by tblDiver.diver_number, tblDiver.first_name,tblDiver.last_name
having MAX(tblDiving.date_of_diving) <= DATEADD(year,-1, GETDATE()) 

拥有就像一个地方,但在集合功能上。试一试。