[英]mysql query, better way to write this?
编辑我知道桌子很乱。 我接管了这个项目,并正在重写PHP,并对数据库进行了重大更改。 我没有问我应该如何布局数据库。 我需要进行快速,临时的修复,并且正在寻找一种更好的方式来编写下面的查询。 结束编辑
嗨,您好!
所以我有这个查询(下面),这还没有完成,并且越来越长。 我想知道是否有一种方法可以缩短它,或者是否有更好的方法来解决它。
SELECT user.*,
cat1id.CategoryName as cat1,
cat2id.CategoryName as cat2,
cat3id.CategoryName as cat3,
cat4id.CategoryName as cat4,
cat5id.CategoryName as cat5,
cat6id.CategoryName as cat6,
cat7id.CategoryName as cat7,
cat8id.CategoryName as cat8,
cat9id.CategoryName as cat9,
cat10id.CategoryName as cat10
FROM users AS user
LEFT JOIN Category cat1id ON user.categoryid = cat1id.id
LEFT JOIN Category cat2id ON user.categoryid_2 = cat2id.id
LEFT JOIN Category cat3id ON user.categoryid_3 = cat3id.id
LEFT JOIN Category cat4id ON user.categoryid_4 = cat4id.id
LEFT JOIN Category cat5id ON user.categoryid_5 = cat5id.id
LEFT JOIN Category cat6id ON user.categoryid_6 = cat6id.id
LEFT JOIN Category cat7id ON user.categoryid_7 = cat7id.id
LEFT JOIN Category cat8id ON user.categoryid_8 = cat8id.id
LEFT JOIN Category cat9id ON user.categoryid_9 = cat9id.id
LEFT JOIN Category cat10id ON user.categoryid_10 = cat10id.id
WHERE user.id = 65447
谢谢!
如果您使用的是Mysql5,则可以尝试编写视图。
所以
CREATE VIEW big_damn_query AS
SELECT user.*,
cat1id.CategoryName as cat1,
cat2id.CategoryName as cat2,
cat3id.CategoryName as cat3,
cat4id.CategoryName as cat4,
cat5id.CategoryName as cat5,
cat6id.CategoryName as cat6,
cat7id.CategoryName as cat7,
cat8id.CategoryName as cat8,
cat9id.CategoryName as cat9,
cat10id.CategoryName as cat10
FROM users AS user
LEFT JOIN Category cat1id ON user.categoryid = cat1id.id
LEFT JOIN Category cat2id ON user.categoryid_2 = cat2id.id
LEFT JOIN Category cat3id ON user.categoryid_3 = cat3id.id
LEFT JOIN Category cat4id ON user.categoryid_4 = cat4id.id
LEFT JOIN Category cat5id ON user.categoryid_5 = cat5id.id
LEFT JOIN Category cat6id ON user.categoryid_6 = cat6id.id
LEFT JOIN Category cat7id ON user.categoryid_7 = cat7id.id
LEFT JOIN Category cat8id ON user.categoryid_8 = cat8id.id
LEFT JOIN Category cat9id ON user.categoryid_9 = cat9id.id
LEFT JOIN Category cat10id ON user.categoryid_10 = cat10id.id;
那么您的查询将是
SELECT * FROM big_damn_query bdq WHERE bdq.id = 65447
如果您不能更改数据库,那么您就在正确的位置。 如果您将不得不使用它,那么将您的混乱转化为更规范化的表或视图也许是个好主意。
编辑:如果要将其转换为(几乎)标准化的视图,则可以执行以下操作:
CREATE VIEW user_category AS
SELECT users.id as user_id, Category.id as category_id
FROM users INNER JOIN Category ON users.categoryid = Category.id
UNION
SELECT users.id, Category.id
FROM users INNER JOIN Category ON users.categoryid_2 = Category.id
UNION
SELECT users.id, Category.id
FROM users INNER JOIN Category ON users.categoryid_3 = Category.id
....
等等。此代码未经测试,但我确定您知道。 您必须测试性能,看看它是否可以接受,但是其中没有任何外部联接。
看起来您需要规范化数据库架构-理想情况下,用户表中重复的categoryid_ n列应取出到单独的表中。
拿起一本有关数据库设计的书并阅读有关关系的知识...
编辑:概括为“关系”。
这个项目我不羡慕你。 看起来好像是充满了反模式。
这是一个建议:查询中的许多外部联接可能会很昂贵。 并且将所有这些类别放在单独的列中是很尴尬的。 尝试以下方法:
SELECT u.*, c.CategoryName
FROM users AS u
LEFT JOIN Category AS c
ON (c.id IN (u.categoryid, u.categoryid_2, u.categoryid_3, u.categoryid_4,
u.categoryid_5, u.categoryid_6, u.categoryid_7, u.categoryid_8,
u.categoryid_9, u.categoryid_10))
WHERE u.id = 65447;
您可以做的另一种技巧(假设您用mysql
标记了这个问题):
SELECT u.*, GROUP_CONCAT(c.CategoryName) AS CatList
FROM users AS u
LEFT JOIN Category AS c
ON (c.id IN (u.categoryid, u.categoryid_2, u.categoryid_3, u.categoryid_4,
u.categoryid_5, u.categoryid_6, u.categoryid_7, u.categoryid_8,
u.categoryid_9, u.categoryid_10))
WHERE u.id = 65447
GROUP BY u.id;
这样会将输出减少到一行,并且所有CategoryName
字符串都连接在一起,并以逗号分隔。 参见GROUP_CONCAT()
。
您的表结构应类似于以下内容:(而不是具有categoryid_x列)(我的语法可能有点过头,并且对此进行了精简,但是应该可以入门)
CREATE TABLE user (
user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE category (
category_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE user_category (
user_id INT NOT NULL,
category_id INT NOT NULL,
PRIMARY KEY (user_id, category_id),
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (category_id) REFERENCES category(category_id)
);
这样建立的是“一对多”关系。 您将能够为任意给定用户分配任意数量的类别。
要检索给定用户的类别:
SELECT *
FROM category
WHERE user = 65447;
如果您坚持使用此数据模型,我不知道您是否真的可以非常优化此SQL。 但是,您可以采取以下措施来帮助您提高所拥有的性能:
假设您坚持使用此模式,并且知道可以使用PHP,则可以始终使用PHP来简化生活。 就像是...
$tables = 10;
$query = "SELECT user.*;
for ( $i = 0; $i <= $tables; $i++) {
$query += ", cat{$i}id.CategoryName as cat{$i} ";
}
$query += " FROM users AS user";
for ( $i = 0; $i <= $tables; $i++) {
$query += " LEFT JOIN Category cat{$i}id ON user.categoryid = cat{$i}id.id ";
}
$query += "WHERE user.id = 65447";
(请原谅我的PHP,我不熟悉它,但希望它足以给您一个主意)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.