【问题标题】:MySQL difficult query among many tables in relational database关系型数据库多表MySQL难查询
【发布时间】:2016-05-31 12:39:36
【问题描述】:

我想请您帮忙解决几个小时以来我一直在努力解决的问题。我只会插入我们需要解决问题的有关他们的信息。

1.) 数据结构:

基本上,我有四个表用于此查询。

  • 表 1:门票。包含有关某些事件的行 出票。具有以下属性:t_idatNight

  • 表 2:票务间隔。票多久了。 属性:ti_idt_idstartDateendDate

  • 表 3:票务分配。票是给什么人的 分配给,连接表。属性:ta_idperson_idti_id

  • 表 4:事件。它包含各种事件,发生在 晚上,肯定有票。属性:e_idperson_idhappenedAtNightstart_dateend_date

2.) 所以,我必须进行查询,列出所有发生在晚上的事件,并且没有属于它们的票,其间隔与票间隔相同。

为此,我需要考虑以下几点:

  1. 事件表的“happenedAtNight”设置为 1。
  2. events 表的 person_id 指向 ticketintervals 表,通过它我可以比较日期。
  3. 在比较日期时,我必须考虑ticketinterval 所属的票是atNight=1。

3.) 我尝试过的:我可以写下我的许多尝试,但我发现最接近解决方案的是:

select * from tickets t, ticketintervals tint, ticketassignments t_ass, events e 
    where t.atNight = 1
    and t.t_id = tint.t_id
    and tint.ti_id = t_ass.ti_id
    and t_ass.person_id = e.person_id
    and e.happenedAtNight = 1
    and date_format(tint.startDate,'%Y-%m-%d') != date_format(e.start_date,'%Y-%m-%d')
    and date_format(tint.endDate,'%Y-%m-%d') != date_format(e.end_date,'%Y-%m-%d')
    ;

但这会将所有与事件日期不同的票间隔与日期配对,因为可能有票在夜间且不属于某个事件,但属于某个人属于一个事件。所以这样我似乎也得到了自己的票,有他们的时间间隔,但我只希望在没有属于他们的时间间隔的票时出现事件

现在真的很简短:我只想在晚上看到没有门票的活动。

我对如何处理这个问题感到非常困惑,我查看了 INNER JOIN 和许多其他方法,但我似乎无法掌握如何将此逻辑连接到 MySQL 方式。

【问题讨论】:

    标签: mysql database relational-database


    【解决方案1】:

    由于您要列出事件,因此您必须先查询此表,然后加入过滤所需的其他表:

    SELECT e.* FROM events e
        LEFT JOIN ticketassignments ta ON e.person_id = ta.person_id
        LEFT JOIN ticketintervals ti ON ta.ti_id = ti.ti_id
        LEFT JOIN tickets t ON ti.t_id = t.t_id
    

    如果结果中需要其他表的信息,只需在SELECT语句中添加即可,例如:

    SELECT e.*, ta.person_id, ti.*
    

    然后过滤只发生在晚上的事件

    WHERE e.happenedAtNight = 1
    

    然后确保门票间隔的日期和事件将仅与夜间发生的门票进行比较。 ticket.atNight = 0时不要比较日期,ticket.atNight = 1时比较:

    AND (t.atNight = 0 OR (t.atNight = 1 
        AND DATE_FORMAT(ti.startDate,'%Y-%m-%d') != DATE_FORMAT(e.start_date,'%Y-%m-%d')
        AND DATE_FORMAT(ti.endDate,'%Y-%m-%d') != DATE_FORMAT(e.end_date,'%Y-%m-%d')
    ));
    

    这是生成的 SQL:

    SELECT e.* FROM events e
        LEFT JOIN ticketassignments ta ON e.person_id = ta.person_id
        LEFT JOIN ticketintervals ti ON ta.ti_id = ti.ti_id
        LEFT JOIN tickets t ON ti.t_id = t.t_id
    WHERE e.happenedAtNight = 1
        AND (t.atNight = 0 OR (t.atNight = 1 
            AND DATE_FORMAT(ti.startDate,'%Y-%m-%d') != DATE_FORMAT(e.start_date,'%Y-%m-%d')
            AND DATE_FORMAT(ti.endDate,'%Y-%m-%d') != DATE_FORMAT(e.end_date,'%Y-%m-%d')
        ));
    

    【讨论】:

    • 你完全是伴郎,我在这里完全不知所措。我将修改我对 JOIN 部分的研究,以便能够更好地使用它们。很好的解释和快速的帮助,非常感谢!
    猜你喜欢
    • 2019-12-09
    • 1970-01-01
    • 2022-01-10
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多