将查询结果限制为2个JOINED表中的一个的行数

时间:2015-01-01 15:04:30

标签: sql sql-server join

我打算将查询结果限制为Section Section中的行(126行) 但我的查询一直为事件表(QUERY 1)或错误消息(QUERY 2)提供725行 如何编写此JOIN查询并将输出限制为Section Table中的行数?

QUERY 1

SELECT      
CASE WHEN e.EventActive='y' 
THEN 'Active' ELSE 'Inactive' END AS EventActive, 
COUNT(*) AS 'Total'
FROM       ADF_Section s
INNER JOIN ADF_Event e
ON          s.SectionID = e.SectionID
GROUP BY
CASE WHEN e.EventActive='y' 
THEN 'Active' ELSE 'Inactive' END

QUERY 2

SELECT      s.*, e.EventActive
FROM        ADF_Section s
INNER JOIN ADF_Event e
ON         s.SectionID = e.SectionID
HAVING     s.CourseID<= 1037
GROUP BY   s.*, e.EventActive

enter image description here enter image description here

2 个答案:

答案 0 :(得分:1)

我想你想要exists

SELECT s.*,
       (CASE WHEN EXISTS (SELECT 1
                          FROM ADF_EVENT e
                          WHERE s.SectionID = e.SectionID AND e.EventActive = 'y'
                         )
             THEN 'y' ELSE 'n'
        END) as EventActive
FROM  ADF_Section s
WHERE s.CourseID <= 1037;

如果您有大量数据,这将受益于索引:ADF_Section(CourseId, SectionId)ADF_Event(SectionId, EventActive)

注意:这假定当与该部分关联的任何事件处于活动状态时,事件处于活动状态。如果逻辑真的是所有需要处于活动状态且至少有一个,则以下逻辑应该有效:

       (CASE WHEN EXISTS (SELECT 1
                          FROM ADF_EVENT e
                          WHERE s.SectionID = e.SectionID
                          GROUP BY e.SectionId
                          HAVING MIN(EventActive) = MAX(EventActive) AND MIN(EventActive) = 'y'
                         )
             THEN 'y' ELSE 'n'

答案 1 :(得分:0)

以下是如何计算每个部分的活动/非活动状态:

select s.SectionID, 
  case 
    -- if all Events in the series are 'y, 
    -- Section is considered 'Active':
    when min(e.EventActive) = 'y' and max(e.EventActive) = 'y' then 'Active'

    -- there are both active and inactive Events,
    -- display NULL (according to your comment):
    when min(e.EventActive) < max(e.EventActive) then null

    -- in case none of the above scenarios are met, 
    -- it means that all Events are inactive, so we 
    -- consider Section to be inactive as well:
    else 'Inactive'
  end as EventActive
from ADF_Section s
join ADF_Event e
  on s.SectionID = e.SectionID
group by s.SectionID;

我在这里创建了一个带有一些随机数据的测试场景:http://www.sqlfiddle.com/#!3/aa0a3/1

如果您需要根据Section过滤CourseID,请在WHERE子句中添加此过滤器,并确保在GROUP BY中也包含已过滤的字段:

select s.SectionID, 
  case 
    when min(e.EventActive) = 'y' and max(e.EventActive) = 'y' then 'Active'
    when min(e.EventActive) < max(e.EventActive) then null
    else 'Inactive'
  end as EventActive
from ADF_Section s
join ADF_Event e
  on s.SectionID = e.SectionID
where s.CourseId <= 1037
group by s.SectionID, s.CourseID;