Postgre:2个不同的查询,但结果相同

时间:2016-12-13 17:58:32

标签: python sql django postgresql django-views

我在postgre sql中遇到问题。 第一个查询:

SELECT first_name, last_name, service_name, max(usluga)
FROM ( SELECT first_name, last_name, service_name, 
              count(scheduler_scheduleevents.id) as usluga
       FROM workers_workers
       LEFT JOIN scheduler_scheduleevents
         ON scheduler_scheduleevents.worker_id = workers_workers.id
        AND is_start_time = True
        AND is_active = False
        AND ( scheduler_scheduleevents.date < %s 
              or ( scheduler_scheduleevents.date = %s and time < %s ) )
       LEFT JOIN user_settings_userservices
         ON user_settings_userservices.id =scheduler_scheduleevents.service_type_id
       WHERE workers_workers.salonid_id= %s
         AND scheduler_scheduleevents.worker_id = %s
       GROUP BY workers_workers.id, service_name
     ) as x
GROUP BY x.first_name, x.last_name, x.service_name

第二:

SELECT first_name, last_name, service_name, min(usluga)
FROM ( SELECT first_name, last_name, service_name, 
              count(scheduler_scheduleevents.id) as usluga
       FROM workers_workers
       LEFT JOIN scheduler_scheduleevents
         ON scheduler_scheduleevents.worker_id = workers_workers.id
        AND is_start_time = True
        AND is_active = False
        AND ( scheduler_scheduleevents.date < %s 
             or ( scheduler_scheduleevents.date = %s and time < %s ) )
       LEFT JOIN user_settings_userservices
         ON user_settings_userservices.id =scheduler_scheduleevents.service_type_id
       WHERE workers_workers.salonid_id= %s
         and scheduler_scheduleevents.worker_id = %s
       GROUP BY workers_workers.id, service_name
    ) as x
GROUP BY first_name, last_name, service_name

第一个查询应该只给我一个服务,这是大部分时间,第二个查询应该只给我一个服务,这是最少的次数。 问题是两个查询都给我相同的结果:所有服务的列表以及每个服务的制作次数。

2 个答案:

答案 0 :(得分:1)

使用cte使其更具可读性,然后使用ROW_NUMBER()查看whois最少和最多。

WITH cte as (
    SELECT first_name, last_name, service_name, 
           count(scheduler_scheduleevents.id) as usluga,
           ROW_NUMBER() OVER (ORDER BY count(scheduler_scheduleevents.id asc) ) as min_usluga,
           ROW_NUMBER() OVER (ORDER BY count(scheduler_scheduleevents.id desc) ) as max_usluga,
           FROM workers_workers
           LEFT JOIN scheduler_scheduleevents
             ON scheduler_scheduleevents.worker_id = workers_workers.id
            AND is_start_time = True
            AND is_active = False
            AND ( scheduler_scheduleevents.date < %s 
                 or ( scheduler_scheduleevents.date = %s and time < %s ) )
           LEFT JOIN user_settings_userservices
             ON user_settings_userservices.id =scheduler_scheduleevents.service_type_id
           WHERE workers_workers.salonid_id= %s
             and scheduler_scheduleevents.worker_id = %s
           GROUP BY workers_workers.id, service_name
)
SELECT *
FROM cte
WHERE min_usluga = 1
--WHERE max_usluga = 1

答案 1 :(得分:0)

我想你正在寻找distinct on。第一个查询将写为:

SELECT DISTINCT ON (first_name, last_name) x.*
FROM (SELECT first_name, last_name, service_name, count(se.id) as usluga
      FROM workers_workers w JOIN
           scheduler_scheduleevents se
            ON se.worker_id = w.id AND is_start_time = True AND
               is_active = False AND
               (se.date < %s or
                se.date = %s and time < %s
               ) LEFT JOIN
           user_settings_userservices uss
           ON uss.id = se.service_type_id
      WHERE w.salonid_id= %s AND se.worker_id = %s
      GROUP BY w.id, service_name
     ) x
ORDER BY first_name, last_name, usluga DESC;

您的查询失败,因为您在外部查询的聚合键中包含service_name。这与内部查询的聚合相同,因此它不执行任何操作。您可以希望 MAX()函数返回具有最大值的行,但这不是MAX()所做的

注意:

  • 表别名使查询更易于编写和阅读。
  • se.worker_id上的条件会将LEFT JOIN变为INNER JOIN,因此没有理由对该表使用LEFT JOIN
  • 您可能真的想要LEFT JOIN,如果是,则条件应该在w.id上。