我有这些表:
颜色
colorId colorName
1 Blu
2 Green
3 Yellow
4 Red
colors_groups
colorsGroupId colorsGroupName
1 BG
2 BY
3 RB
colors_groups_ids
colorsGroupId colorId colorOrder
1 1 1
1 2 2
2 1 1
2 2 3
3 4 1
3 1 2
books_covers
bookId colorsGroupId
1 1
1 2
2 2
是否可以提供这样的结果视图?
bookId colorsGroupIds colorsGroupName
1 1,2 BG (Blu/Green), BY (Blu/Yellow)
2 2 BY (Blu/Yellow)
我用group_by尝试了两个视图,将第二个视图加入第一个视图的速度非常慢。 任何帮助将不胜感激。
编辑。我尝试了您的视图而不是我的视图,但是SELECT的速度很慢,而mysql解释了这样的查询:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3320
2 DERIVED colors_groups ALL NULL NULL NULL NULL 3320 Using filesort
2 DERIVED colors_groups_ids ref colorsgroupid colorsgroupid 3 colorsgroupid 1
2 DERIVED colors eq_ref PRIMARY PRIMARY 2 colors.colorId 1 Using where
3220是color_groups记录的数量。为什么使用filesort并获得每3320条记录两次?
这是查询:
SELECT
groups.colorsGroupId, groups.colorsGroupName,
GROUP_CONCAT(groups_ids.colorId ORDER BY groups_ids.order ASC) AS colors_ids,
GROUP_CONCAT(colors.colorName ORDER BY groups_ids.order ASC SEPARATOR "/") AS colors_names,
CONCAT(groups.colorsGroupName, " (", GROUP_CONCAT(colors.colorName ORDER BY groups_ids.order ASC SEPARATOR "/"), ")") AS colors_names_complete,
FROM colors_groups AS groups
JOIN colors_groups_ids group_ids
ON groups.colorsGroupId=group_ids.colorsGroupId
JOIN colors
ON group_ids.colorId=colors.colorId
GROUP BY groups.colorsGroupId, groups.colorsGroupName
答案 0 :(得分:0)
请注意,使用视图非常不利于MySQL,因此在我看来,它们没有任何用处。
请考虑以下内容:
DROP TABLE IF EXISTS colors;
CREATE TABLE colors
(colorId SERIAL PRIMARY KEY
,colorName VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO colors VALUES
(11,'Blu'),
(12,'Green'),
(13,'Yellow'),
(14,'Red');
DROP TABLE IF EXISTS color_groups;
CREATE TABLE color_groups
(colorsGroupId SERIAL PRIMARY KEY
,colorsGroupName CHAR(2) NOT NULL UNIQUE
);
INSERT INTO color_groups VALUES
(101,'BG'),
(102,'BY'),
(103,'RB');
DROP TABLE IF EXISTS colors_groups_ids;
CREATE TABLE colors_groups_ids
(colorsGroupId INT NOT NULL
,colorId INT NOT NULL
,colorOrder INT NOT NULL
,PRIMARY KEY(colorsGroupId,colorid)
);
INSERT INTO colors_groups_ids VALUES
(101,11,1),
(101,12,2),
(102,11,1),
(102,13,2), -- note: fixed the error in the original data set
(103,14,1),
(103,11,2);
DROP TABLE IF EXISTS book_covers;
CREATE TABLE book_covers
(bookId INT NOT NULL
,colorsGroupId INT NOT NULL
,PRIMARY KEY(bookid,colorsgroupid)
);
INSERT INTO book_covers VALUES
(1001,101),
(1001,102),
(1002,102);
SELECT b.bookid
, GROUP_CONCAT(DISTINCT x.colorsgroupid ORDER BY x.colorsgroupid) colorsgroupids
, GROUP_CONCAT(DISTINCT x.colorsgroupname ORDER BY x.x.colorsgroupid) colorgroupname
FROM book_covers b
JOIN
( SELECT g.colorsgroupid
, CONCAT(g.colorsgroupname,' (',GROUP_CONCAT(c.colorname ORDER BY gc.colororder SEPARATOR '/' ),')') colorsgroupname
FROM color_groups g
JOIN colors_groups_ids gc
ON gc.colorsgroupid = g.colorsgroupid
JOIN colors c
ON c.colorid = gc.colorid
GROUP
BY g.colorsgroupid
, g.colorsgroupname
) x
ON x.colorsgroupid = b.colorsgroupid
GROUP
BY b.bookid;
+--------+----------------+--------------------------------+
| bookid | colorsgroupids | colorgroupname |
+--------+----------------+--------------------------------+
| 1001 | 101,102 | BG (Blu/Green),BY (Blu/Yellow) |
| 1002 | 102 | BY (Blu/Yellow) |
+--------+----------------+--------------------------------+
最后,可以看出,该查询使用CONCAT和GROUP_CONCAT。但是,除非使用其他一些聚合函数(SUM / MAX / AVG),否则我认为最好在应用程序代码中处理这种事情。
答案 1 :(得分:0)
我“解决”了以下观点:
colors_groups_view
SELECT
colors_groups.colorsGroupId,
colors_groups.colorsGroupName,
colors_groups_ids.colorId,
colors_groups_ids.order,
colors.colorName
FROM colors_groups
LEFT JOIN colors_groups_ids ON colors_groups_ids.colorGroupId=colors_groups.colorGroupId
LEFT JOIN colors ON colors_groups.colorId=colors.colorId
此视图给出如下结果:
colorsGroupId colorsGroupName colorId order colorName
1 BG 1 1 Blue
1 BG 2 2 Green
2 BY 1 1 Blue
2 BY 3 2 Yellow
然后:
books_view
SELECT
books.bookId,
(
SELECT
GROUP_CONCAT(
(
SELECT
CONCAT(colors_groups_view.colorsGroupName, " (", GROUP_CONCAT(colors_groups_view.colorName ORDER BY colors_groups_view.order ASC SEPARATOR "/"), ")", "") AS booksGroupsNames
FROM colors_groups_view
WHERE colors_groups_view.colorsGroupId=books_covers.colorsGroupId
GROUP BY colors_groups_view.colorsGroupId
)
SEPARATOR ", "
)
FROM books_covers
WHERE books_covers.bookId=books.bookId
GROUP BY books_covers.bookId
) AS booksGroupsNames
FROM books
由于第一个没有GROUP_BY任何东西,因此速度非常快。我不知道是否可以避免这种情况,是否只能在一个查询中完成所有操作。