具有多个条件和子选择的SQL查询

时间:2015-08-28 14:26:25

标签: mysql sql

我很擅长使用连接并从多个表中进行选择。我已经成功地找到了如何根据许多条件从2个表中获取数据。现在我的问题是,只有在满足另一个条件时才需要返回计数。这个想法是这样的: 我有一个查询,返回特定时间特定状态的项目数。我对此的疑问是:

.factory('Articles1', function ($http, $location) {
    // ...

    return {
        all: function () {
            var currentCategory = $location.path().split('/')[1]; // Assuming the category is part of the path and at the second place
            var wpUrl = 'http://www.example.com/wp-json/posts?filter[category_name]=' + currentCategory;

            return $http.get(wpUrl).then(function (response) { // ...

现在我必须检查它是否处于不同的状态,让我们先说sh.status_id = 50,它在57之前。它也不必落在指定的数据范围内。所以我基本上需要以某种方式更改我的查询,以便选择它是否曾经在status_id 50中,然后只有在找到这两种状态时才返回结果。 sh.status_id = 57将受指定日期的约束。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

我假设主键是item_id?

您只需通过主键和status_id = 50连接相同的表。

对于这种情况,我将使用INNER JOIN(我的偏好),但您可以使用FROM / WHERE CLAUSE。

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;

但如果您更喜欢WHERE,您可以执行以下操作:

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;

答案 2 :(得分: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;