【问题标题】:MySQL field from UNION SUBSELECT来自 UNION SUBSELECT 的 MySQL 字段
【发布时间】:2011-11-30 13:37:48
【问题描述】:

我的数据库有以下表格:

  • t1:博客文章
  • t2:每篇博文的附加表
  • t3:博客文章的英文 cmets
  • t4:用于博客文章的西班牙语 cmets

我有以下用例: 我需要获取每篇博文的最新评论的 ID 以及博文本身。最新的评论可能在 t3 或 t4 表中。

我想出了以下 sql,但它没有按预期工作。

SELECT t1.id,
t1.one, 
t1.two, 
(
    SELECT id FROM (
        (SELECT * FROM t3 where t3.refid = t1.id) 
        UNION (SELECT * FROM t4 where t4.refid = t1.id) 
        ORDER BY datetime ASC LIMIT 1
    ) AS tempTable) 
AS someValue
FROM t1 
LEFT JOIN t2 ON (t1.id = t2.id) 
WHERE t1.otherid=42 AND t1.somefield > 0 
ORDER BY t1.someOtherField 
LIMIT 5

非常感谢任何关于是否和/或如何实现这一点的提示,谢谢!

【问题讨论】:

  • 当您说它没有按预期工作时,当前发生了什么?此外,表 t3 和 t4 是否具有唯一的主键,例如,如果您要显示英文评论而不是西班牙文评论,您将如何检测?
  • 对不起,我应该在帖子里写的。 mysql 说“未知列 t1.id”,似乎子选择无法访问来自外部查询的数据。这可能是因为子选择在 select_expr 中,而不是在 where_condition 中。
  • 我想显示包含最新评论的表格中的评论。当然,真正的表中有键 - 这些只是虚拟的.. ;)
  • 我明白了。一种可能性是您将 t3/t4 联合封装在一个视图中,提供一种访问所有 cmets 的方法,然后子选择应该可以工作。这具有任何其他引用 cmets 的代码的额外好处,可以使用视图而无需重复联合逻辑。我想我很想问为什么 cmets 不在一个带有表示英语或西班牙语的语言属性的表中?
  • 刚刚发现mysql没有物化视图。我的 t3/t4 表有 ~100.000.000 个条目,所以很遗憾你的建议对我不起作用。

标签: mysql sql select union subquery


【解决方案1】:

您需要将包含 t3 和 t4 中最新 cmets 的表编译成表 d 然后也将这两个结果合并到 cmets 表中cc 将仅包含 1 个条目,即来自 t3 或来自 t4 的最新 id

c.t 会告诉你从哪个表得到响应;

SELECT t1.*, 
       t2.*, 
       c.id AS cid, 
       c.dt AS dt, 
       c.t  AS t 
FROM   t1 
       LEFT JOIN t2 
         ON ( t1.id = t2.id ) 
       LEFT JOIN (SELECT d.id, 
                         Max(d.dt) AS dt, 
                         d.refid, 
                         d.t       AS t 
                  FROM   (SELECT t3.id, 
                                 Max(DATETIME) AS dt, 
                                 t3.refid, 
                                 3             AS t 
                          FROM   t3 
                          GROUP  BY t3.refid 
                          UNION ALL 
                          SELECT t4.id, 
                                 Max(DATETIME) AS dt, 
                                 t4.refid, 
                                 4             AS t 
                          FROM   t4 
                          GROUP  BY t4.refid) d 
                  GROUP  BY d.refid) c 
         ON c.refid = t1.id; 

【讨论】:

    【解决方案2】:

    先试试这个查询,它应该返回来自 t3 和 t4 的最新 cmets -

    SELECT t_comments1.* FROM (SELECT * FROM t3 UNION SELECT * FROM t4) t_comments1
      JOIN (SELECT refid, MAX(datetime) max_datetime FROM (SELECT * FROM t3 UNION SELECT * FROM t4) t GROUP BY t.refid) t_comments2
        ON t_comments1.refid = t_comments2.refid AND t_comments1.datetime = t_comments2.max_datetime;
    

    如果没问题,那么让我们将此查询与 t1 表结合起来 -

    SELECT t1.*, t_comments.* FROM t1
      LEFT JOIN (
        SELECT t_comments1.* FROM (SELECT * FROM t3 UNION SELECT * FROM t4) t_comments1
          JOIN (SELECT refid, MAX(datetime) max_datetime FROM (SELECT * FROM t3 UNION SELECT * FROM t4) t GROUP BY t.refid) t_comments2
            ON t_comments1.refid = t_comments2.refid AND t_comments1.datetime = t_comments2.max_datetime
      ) t_comments
      ON t1.id = t_comments.refid;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      相关资源
      最近更新 更多