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