【问题标题】:Possible alternatives to a bunch of sub Queries [closed]一堆子查询的可能替代方案[关闭]
【发布时间】:2013-07-30 16:33:09
【问题描述】:

我正在根据子查询查询表 1 中的日期列。 where 子句中的子查询 1 从外键引用的表中获取描述,子查询 2 通过其他条件提取数据。

所以我的问题是,我有什么替代方法可以使这个查询更好?

SELECT count(*) AS non_saturday
FROM t_booking
WHERE p_id IN (
        SELECT p_id
        FROM p_detail
        WHERE p_name IN ('A','B')
        )
    AND date_format(p_date, '%Y%m%d') IN (
        SELECT DISTINCT CONCAT (
                gregorian_ccyy
                ,gregorian_month
                ,gregorian_day
                )
        FROM m_gregorian_calendar1 c
        WHERE c.day_of_the_week = (
                SELECT day_id
                FROM m_gregorian_day
                WHERE day_name = 'SATURDAY'
                )
            AND c.gregorian_ccyy = '2012'
            AND c.gregorian_month = '10'
        )

【问题讨论】:

  • 一个建议是考虑使用 JOIN 而不是子查询。
  • 正如@bluefeet 提到的,您似乎可以简单地加入您的三个表而不是使用子查询。但是,您不想使用 date_format/concatenation 业务来加入表,因为这不允许使用索引。
  • 我忘了提到我添加的 2012 年和第 10 个月是硬编码的,因为这是来自表单。正如建议的那样,我可以使用内部联接,但我认为它会使查询的可读性降低。
  • 任何无法阅读连接语法的人都没有资格从事涉及编写查询的工作。

标签: mysql sql subquery


【解决方案1】:

这可能不是您问题的直接答案,但如果您所说的“星期六”是指直接的星期六(与日期和星期几之间具有不同映射的某些日历相反),在我看来你可以简单地运行

SELECT count(*) AS non_saturday
    FROM t_booking
    JOIN p_detail ON (t_booking.p_id = p_detail.p_id AND p_name IN ('A','B'))
    WHERE
        DAYOFWEEK(p_date) = 7
        AND MONTH(p_date) = 10
        AND YEAR (p_date) = 2012

或者为了更好地在p_date字段上使用索引,

    WHERE p_date BETWEEN "2012-10-01" AND "2012-10-31"

(但关于在日期字段中使用BETWEEN,还要检查this answer)。

【讨论】:

  • 这太棒了。不知道 dayofweek 功能。我可以在此处直接使用它,而不是从具有沿函数行的 day_of_week 列的日历表中过滤。我不明白的一件事是为什么 on 子句中的 and 条件?
  • 那是因为p_detail 表有一个基于p_nameWHERE 条件,所以我不能直接创建JOIN,必须添加WHERE 的等效项。您可能想查看一些关于使用 JOINs 的教程(也许还有索引)。
猜你喜欢
  • 2017-11-06
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
相关资源
最近更新 更多