【问题标题】:Postgre: 2 different query but same resultPostgre:2个不同的查询但结果相同
【发布时间】:2017-04-28 21:36:17
【问题描述】:

我在 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

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

【问题讨论】:

    标签: python sql django postgresql django-views


    【解决方案1】:

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

    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
    

    【讨论】:

      【解决方案2】:

      我想你正在寻找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

      【讨论】:

      • 非常感谢。我必须了解不同功能的工作原理:P
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多