【问题标题】:MySQL - where clause on triple nested selectMySQL - 三重嵌套选择的 where 子句
【发布时间】:2018-03-14 22:34:33
【问题描述】:

我正在编写我个人做过的最复杂的查询......我被卡住了!

代码如下:

SELECT 
    el.UID, 
    (
        SELECT 
            SUM(booked)  
        FROM 
            (
                SELECT 
                ts.*, max(ts.dateStored) 
                FROM eventsDetails ed 
                JOIN ticketSales ts ON ts.DUID = ed.UID 
                WHERE ed.event_masterEvent = 1147 
                GROUP BY ts.DUID
            ) a 
    ) as booked,
    el.event_confirmed, 
    el.event_title, 
    (
        SELECT 
            GROUP_CONCAT(g.colour) 
        FROM eventsGenre eg 
        JOIN genres g ON g.UID = eg.GUID 
        WHERE eg.EUID = el.UID
    ) AS genreCodes, 
    (
        SELECT 
            GROUP_CONCAT(g.genre) 
        FROM eventsGenre eg 
        JOIN genres g ON g.UID = eg.GUID 
        WHERE eg.EUID = el.UID
    ) AS genreNames 
FROM eventsList el 
JOIN eventsDetails ed ON el.UID = ed.event_masterEvent 
WHERE el.event_active='1' 
AND ed.event_eventDateAndTime >= CURDATE() 
GROUP BY el.UID 
ORDER BY ed.event_eventDateAndTime ASC

在“WHERE ed.event_masterEvent = 1147”这一行上,我不想将其更改为“WHERE ed.event_masterEvent = el.UID”。 1147 只是为了测试代码是否有效……但现在我需要引用整个事件 ID。

每当我这样做时,我都会收到一条错误消息,指出该列不存在。

我不明白,因为在查询的后面,我可以在子选择中说“WHERE eg.EUID = el.UID”。

我不知道我做错了什么......正如我之前所说,我现在非常远离我的舒适区,正在寻找一些 MySQL 专家来解释我在哪里出错了。

我感觉我需要在某个地方添加另一个联接,但我不知道在哪里。我试图寻找答案,但我不确定要使用什么搜索词 - 所以我没有走得太远。

任何帮助将不胜感激!

这里有一个问题:http://sqlfiddle.com/#!9/c77a98/2

【问题讨论】:

  • 我不明白你为什么需要嵌套的SELECT。未使用的MAX(ts.dateStored) 有什么意义?
  • 如果您试图为每个DUID 获取最后一个ts.dateStoredbooked 值,那不是正确的方法。见row with max value of a column
  • 正如我所说 - 我是新手......所以谢谢你的建议。我去看看。但是,是否有原因我无法从嵌套选择中引用 el.UID - 或者有没有办法做到这一点?
  • 来自manual:派生表(SELECT 的 FROM 子句中的子查询)不能包含外部引用或对同一 SELECT 的其他表的引用
  • ed.UID和ed.event_masterEvent之间是否有1:1的对应关系?

标签: mysql sql


【解决方案1】:

您发布的查询过于复杂,如果您使用一些JOINs,则可以使其更具可读性。

我已经设法重写(未经测试)您的大部分查询,如下所示,但我不确定重构 booked 部分,因为在没有可靠架构和示例的情况下不清楚您要实现什么参考数据。

如果您想用您的架构和数据创建一个有效的 SQL 小提琴,我会努力完成它。如果没有,希望以下内容可以帮助您简化和解决问题。

SELECT 
    el.UID,
    el.event_confirmed, 
    el.event_title, 
    GROUP_CONCAT(DISTINCT g.genre SEPARATOR ', ') AS genreNames,
    GROUP_CONCAT(DISTINCT g.colour SEPARATOR ', ') AS genreCodes,
    SUM(ts.booked) AS booked
FROM eventsList el
INNER JOIN eventsDetails ed ON (el.UID = ed.event_masterEvent AND ed.event_eventDateAndTime >= CURDATE())
LEFT JOIN eventsGenre eg ON (el.UID = eg.EUID)
LEFT JOIN genres g ON (eg.GUID = g.UID)
LEFT JOIN (
    SELECT ts.*, MAX(ts.dateStored)
    FROM eventsDetails ed 
    INNER JOIN ticketSales ts ON ts.DUID = ed.UID 
    GROUP BY ts.DUID
) AS ts ON (ed.UID = ts.DUID)
WHERE el.event_active = 1
AND el.UID = 1147
GROUP BY el.UID
ORDER BY ed.event_eventDateAndTime ASC;

【讨论】:

  • 你应该在GROUP_CONCATs 中使用DISTINCT,否则你会因为额外的连接而得到重复。但是这个答案并没有解决他查询中的真正问题,即如何获得他想要的booked 值。
  • 请致电DISTINCT。我意识到它现在不能回答他的问题,但是他发布的查询是一团糟,所以我试图简化它,并且通过 OP 提供的更多信息,我也可以回答他的问题。但正如我在回答中所说,他可以接受或离开。
  • 我以前从未创建过小提琴......我现在只是在检查它。我不怀疑查询过于复杂......但是,我正在努力变得更好:)
  • 我认为您需要加入一个获得SUM(booked) ... GROUP BY event_masteruid, DUID 的子查询,并加入el.UID = DUID
  • 由于没有使用MAX(ts.dateStored),我想只使用LEFT JOIN ticketSales ts ON (ed.UID = ts.DUID)SUM(ts.booked) AS booked,因为GROUP BY el.UID 应该处理聚合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多