Mysql 无法使用包含子查询的查询创建视图,我可以做什么?

Mysql 无法使用包含子查询的查询创建视图,我可以做什么?,mysql,sql,Mysql,Sql,我想为数据库中的表创建一个视图,以便在联接中更轻松地使用它。表UserSettings如下所示: mysql> desc UserSettings; -- cut the output for readability +-----------+--------------------- | Field | Type +-----------+--------------------- | userID | bigint(20) unsign

我想为数据库中的表创建一个视图,以便在联接中更轻松地使用它。表UserSettings如下所示:

mysql> desc UserSettings;  -- cut the output for readability 
+-----------+---------------------
| Field     | Type                
+-----------+---------------------
| userID    | bigint(20) unsigned 
| timestamp | timestamp           
| settingID | text                
| setting   | text                
+-----------+---------------------
4 rows in set (0.00 sec)
我们在其中存储用户设置的每次更新。现在,我想为该表创建一个视图,其中包含每个用户的最新设置。因此,我希望视图包含标有*的行:

我可以通过包含子查询的查询执行此操作:

mysql> SELECT us.* 
    -> FROM  UserSettings us INNER JOIN (
    ->     SELECT userID, settingID, max(timestamp) as timestamp 
    ->     from UserSettings 
    ->     group by userID, settingID) ts ON ts.userID = us.userID AND 
    ->   ts.settingID = us.settingID AND ts.timestamp = us.timestamp;
+--------+---------------------+-----------------------+---------+
| userID | timestamp           | settingID             | setting |
+--------+---------------------+-----------------------+---------+
|    123 | 2014-04-17 10:04:22 | settings.test         | bar     |
|    123 | 2014-04-17 06:49:08 | settings.warnings_off | 0       |
|    911 | 2014-04-17 10:07:40 | settings.test         | bar     |
|    911 | 2014-04-17 06:49:33 | settings.warnings_off | 1       |
+--------+---------------------+-----------------------+---------+
4 rows in set (0.00 sec)
但是,当在CREATEVIEW CurrentUserSettings AS中使用上述查询时,我得到错误1349 HY000:View的SELECT在FROM子句中包含一个子查询


有没有办法创建UserSettings表的视图,以显示与上述查询相同的数据?也许以某种方式使用have?

就像Kickstart建议的那样,这样做吧

首先,在视图中创建子查询

CREATE VIEW subqueryview as 
SELECT userID, settingID, max(timestamp) as timestamp 
from UserSettings group by userID, settingID;
然后可以使用视图创建视图

CREATE VIEW finalview AS 
SELECT us.* 
FROM UserSettings us 
-- Here you now use the view created.
INNER JOIN  subqueryview ts 
ON ts.userID = us.userID 
AND ts.settingID = us.settingID 
AND ts.timestamp = us.timestamp;

要扩展我在上面的评论:-

CREATE VIEW latest_timestamp AS SELECT userID, settingID, max(timestamp) as timestamp 
    from UserSettings 
    group by userID, settingID;

CREATE VIEW latest_timestamp AS SELECT us.* 
FROM  UserSettings us 
INNER JOIN latest_timestamp ts 
ON ts.userID = us.userID AND 
ts.settingID = us.settingID 
AND ts.timestamp = us.timestamp;
另一种选择是滥用GROUP_CONCAT函数。我并不热衷于这样做,如果字段可以包含NULL,那么就会出现问题,加上is需要将整数转换为字符字段

假设所需字段名为field1、field2和field3,则:-

SELECT us.userID,
        us.settingID,
        SUBSTRING_INDEX(GROUP_CONCAT(us.field1 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1),
        SUBSTRING_INDEX(GROUP_CONCAT(us.field2 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1),
        SUBSTRING_INDEX(GROUP_CONCAT(us.field3 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1)
FROM  UserSettings us 
GROUP BY us.userID, us.settingID;

这是通过将一个字段的所有值连接成一个值,按时间戳降序排列,并在它们之间加上分隔符(任何字段中都不会有分隔符),然后使用子字符串索引将字段添加到第一个分隔符。

您可以设置一个视图,该视图是您的子查询,然后,您可以设置上述查询,但要针对视图进行连接,而不是实际包含子对象query@Kickstart这确实有效,但我更希望不必创建单独的视图,仅用于创建CurrentUserSettings视图的联接。我同意您的偏好,但不确定是否有有效的替代方案。您在最终视图的“创建”视图中有一个子选择。我想只要在那里使用subqueryview就行了。
SELECT us.userID,
        us.settingID,
        SUBSTRING_INDEX(GROUP_CONCAT(us.field1 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1),
        SUBSTRING_INDEX(GROUP_CONCAT(us.field2 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1),
        SUBSTRING_INDEX(GROUP_CONCAT(us.field3 ORDER BY timestamp DESC SEPARATOR '|~|~'), '|~|~', 1)
FROM  UserSettings us 
GROUP BY us.userID, us.settingID;