2015-08-28 246 views
1

我对使用连接和从多个表中进行选择相当新颖。我已经成功地想出了如何根据许多条件从2个表中获取数据。现在我的问题是,只有在满足其他条件的情况下,我才需要返回计数。这个想法是这样的: 我有一个查询,返回在特定时间处于特定状态的项目数量。我对这个查询:具有多个条件和子选择的SQL查询

SELECT count(*), 
     e.campus_id, 
     e.course_id 
FROM statuses_history AS sh, 
    enrolments AS e 
WHERE sh.date_added > '2015-08-01 00:00:00' 
    AND sh.date_added < '2015-08-20 23:59:59' 
    AND sh.status_id = 57 
    AND sh.item_id = e.enrolment_id 
    AND (e.course_id = 2 
     OR e.course_id =7 
     OR e.course_id = 8 
     OR e.course_id = 9) 
GROUP BY e.campus_id, 
     e.course_id; 

现在我必须检查它已经在不同的状态,可以说sh.status_id = 50是在57之前,它也没有落入数据中指定的范围。所以我基本上需要以某种方式更改我的查询,以选择它是否曾经在status_id 50中,然后只在找到两个状态时才返回结果。 sh.status_id = 57将被指定的日期绑定。

在此先感谢您的帮助。

回答

1

您可以根据需要调整子查询,但如果在数据库中找到另一个值,则会返回一行。

我不喜欢子选择,但这应该工作。我没有测试过这个语法。

select count(*), e.campus_id, e.course_id 
FROM statuses_history as sh, enrolments as e 
WHERE sh.date_added > '2015-08-01 00:00:00' 
     AND sh.date_added < '2015-08-20 23:59:59' 
     AND sh.status_id = 57 
     AND sh.item_id = e.enrolment_id 
     AND (e.course_id = 2 OR e.course_id =7 
      OR e.course_id = 8 OR e.course_id = 9) 
     AND EXISTS (select sh2.status_id from statuses_history as sh2 
       WHERE NOT sh2.status_id = 57 
        AND sh2.item_id = e.enrolment_id) 
GROUP BY e.campus_id, e.course_id; 
+0

很好的答案。尽管你在“AND EXISTS(从statuses_history中选择sh2.status_id”)中犯了一个错误,但我只是添加了“as sh2”,但除此之外它完美地工作,谢谢。 –

1

我假定主键是item_id?

您只需在主键和STATUS_ID = 50

对于这种情况,我将使用INNER JOIN(我的偏好)加入到同一个表,但你可以使用FROM/WHERE子句。

select count(*), e.campus_id, e.course_id 
FROM statuses_history as sh, enrolments as e 

INNER JOIN statuses_history AS oldSh ON oldSh.item_id = sh.item_id AND oldSh.status_id = 50 

WHERE sh.date_added > '2015-08-01 00:00:00' AND sh.date_added < '2015-08-20 23:59:59' AND sh.status_id = 57 and sh.item_id = e.enrolment_id AND (e.course_id = 2 OR e.course_id =7 OR e.course_id = 8 OR e.course_id = 9) 
GROUP BY e.campus_id, e.course_id; 

但是,如果你更喜欢哪里,你可以做到以下几点:

select count(*), e.campus_id, e.course_id 
FROM statuses_history as sh, enrolments as e, statuses_history AS oldSh ON 
WHERE oldSh.item_id = sh.item_id AND oldSh.status_id = 50 AND 
sh.date_added > '2015-08-01 00:00:00' AND sh.date_added < '2015-08-20 23:59:59' AND sh.status_id = 57 and sh.item_id = e.enrolment_id AND (e.course_id = 2 OR e.course_id =7 OR e.course_id = 8 OR e.course_id = 9) 
GROUP BY e.campus_id, e.course_id; 
1

添加一个左连接,并使用一个case语句做你的计数。

LEFT JOIN statuses_history sh2 ON sh2.item_id = e.enrollment_id AND sh2.status_id = 50 

您需要为内连接使用不同的格式才能进行左连接。这里是新的查询:

select count(sh.status_id), e.campus_id, e.course_id , SUM(CASE WHEN sh2.status_id IS NOT NULL THEN 1 ELSE 0 END) as cnt 
FROM statuses_history sh 
INNER JOIN enrolments e ON sh.item_id = e.enrolment_id 
LEFT JOIN statuses_history sh2 ON sh2.item_id = e.enrollment_id AND sh2.status_id = 50 
WHERE sh.date_added > '2015-08-01 00:00:00' AND sh.date_added < '2015-08-20 23:59:59' AND sh.status_id = 57 AND (e.course_id = 2 OR e.course_id =7 OR e.course_id = 8 OR e.course_id = 9) 
GROUP BY e.campus_id, e.course_id;