【问题标题】:How do I join one table onto another where userid = userid but only for that date?如何将一个表连接到另一个用户 ID = 用户 ID 但仅针对该日期的表?
【发布时间】:2011-06-29 16:48:02
【问题描述】:

我希望了解用户在他的工作站上处理每批的总时间、估计完成的总工作量、支付给用户的金额以及用户今年每天的失败次数.如果我可以将所有这些加入到一个查询中,那么我可以在 excel 中使用它,并在数据透视表等中很好地格式化。

编辑:我意识到只能在多个查询中执行此操作,因此我将范围缩小到此:

SELECT batch_log.userid,
batches.operation_id,
SUM(TIME_TO_SEC(ramses.batch_log.time_elapsed)),
SUM(ramses.tasks.estimated_nonrecurring + ramses.tasks.estimated_recurring),
DATE(start_time)
FROM batch_log
JOIN batches ON batch_log.batch_id=batches.id
JOIN ramses.tasks   ON ramses.batch_log.batch_id=ramses.tasks.batch_id
JOIN protocase.tblusers on ramses.batch_log.userid = protocase.tblusers.userid
WHERE DATE(ramses.batch_log.start_time) > "2011-01-01"
AND protocase.tblusers.active = 1
GROUP BY userid, batches.operation_id, start_time
ORDER BY start_time, userid ASC

交叉连接导致了问题。

【问题讨论】:

    标签: mysql sql group-by having having-clause


    【解决方案1】:

    不,通常Having 子句用于过滤您的Group by 的结果 - 例如,仅报告那些在一天内支付超过 24 小时的人 (HAVING SUM(ramses.timesheet_detail.paidTime) > 24)。除非您需要对聚合结果进行过滤,否则您根本不需要 having 子句。
    这些条件中的大多数应移至where 子句中,或作为联接的一部分,原因有两个 - 1) 通常应尽快完成过滤,以限制查询需要执行的工作。 2) 如果过滤已经完成,重新声明它可能会导致查询执行额外的、不需要的工作。
    从我目前看到的情况来看,您似乎正试图按天汇总 - 尝试将 group by 子句中的最后一列更改为 date(ramses.batch_log.start_time),或者您正在分组(我假设是)一个时间戳。


    编辑:
    关于模式名称 - 是的,您可以在 fromjoin 部分中命名它们。通常,查询也可能能够根据一些默认搜索列表解析所需的架构(如何设置或是否设置取决于您的数据库)。
    以下是我将如何重新格式化查询:
    SELECT tblusers.userid, operations.name AS name,
    SUM(TIME_TO_SEC(batch_log.time_elapsed)) AS time_elapsed,
    SUM(tasks.estimated_nonrecurring + tasks.estimated_recurring) AS total_estimated,
    SUM(timesheet_detail.paidTime) as hours_paid,
    DATE(start_time) as date_paid
    FROM tblusers
    JOIN batch_log 
    ON tblusers.userid = batch_log.userid 
    AND DATE(batch_log.start_time) >= "2011-01-01" 
    JOIN batches 
    ON batch_log.batch_id = batches.id
    JOIN operations 
    ON operations.id = batches.operation_id
    JOIN tasks
    ON batches.id = tasks.batch_id
    JOIN timesheet_detail 
    ON tblusers.userid = timesheet_detail.userid 
    AND batch_log.start_time = timesheet_detail.for_day
    AND DATE(timesheet_detail.for_day) = DATE(start_time)
    WHERE tblusers.departmentid = 8
    GROUP BY tblusers.userid, name, DATE(batch_log.start_time)     
    ORDER BY date_paid ASC 
    

    特别值得关注的是batch_log.start_time = timesheet_detail.for_day 行,它正在比较(隐含的)时间戳。这些真的平等吗?我希望其中一个或两个应该包含在 date() 函数中。

    至于为什么您可能会收到意外数据 - 您似乎已经消除了一些连接条件。在不知道您的数据库的确切设置和使用的情况下,我无法给出您的结果的确切原因(甚至无法说它们是错误的),但我认为您在没有任何 join 的情况下加入 operations 表这一事实条件可能是罪魁祸首 - 如果该表中有 2 条记录,它将使您之前的所有结果翻倍,看起来可能有 12 条。您还从 group by 子句中删除了 operations.name,这可能是也可能是没有给你想要的结果。我会调查您的其他表格关系,看看是否需要进一步限制。

    【讨论】:

    • 是的。对不起,我的问题措辞太糟糕了。我对这个 sql 东西太不满意了。我现在只做了大约 2 年的开发人员,我的大部分 sql 都通过了 rails (完成了 90% 的工作)。我知道我有办法使用 sql。
    • 另外,我知道读取没有缩进的文件可能很难,但我真的不确定 SQL 中的正确编码风格
    • 没关系,我们都必须从某个地方开始。一些 SQL 风格的 cmets:一般来说,我总是尝试将关系链接放入连接中,ANDed 和 ORed 适当地(这使得关系更加明显),并且倾向于将 where 子句用于单独使用的标准对于from 子句中列出的表。另外,为什么group by 子句中有一个空白字符串 - 因为这是恒定的,它不应该有任何影响。考虑从语句中删除您的架构名称,因为这将允许在必要时移动表,而无需更新语句。
    • 至于模式名称,我在哪里声明它们以便我可以在不命名它们的完整路径的情况下使用它们?在 from 和 join 部分?不过,关系链接,你能详细说明一下吗?
    • 空白字符串也只是错误粘贴在那里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    相关资源
    最近更新 更多