目前,我正在为我的框架Scaffold编写一个模型系统。但是,我的SQL技能并不是那么好。我的系统目前正在产生这个查询。
SELECT
`User`.`id` AS `User_id`,
`User`.`name` AS `User_name`,
`Address`.`id` AS `Address_id`,
`Address`.`address` AS `Address_address`,
`Address`.`user_id` AS `Address_user_id`,
`Database`.`id` AS `Database_id`,
`Database`.`user_id` AS `Database_user_id`
FROM
`users` AS `User`,
`addresses` AS `Address`,
`databases` AS `Database`
GROUP BY `User_id`,`Address_id`,`Database_id`
HAVING
`User`.`id` = 1 AND
`Address`.`user_id` = `User`.`id` AND
`Database`.`user_id` = `User`.`id`;
产生这个结果。
User_id User_name Address_id Address_address Address_user_id Database_id Database_user_id
======= ========= ========== =============== =============== =========== ================
1 Nat 1 1234 1 1 1
1 Nat 1 1234 1 2 1
1 Nat 2 3456 1 1 1
1 Nat 2 3456 1 2 1
这样做很好,但我知道我可能不是最好的方式(我应该使用真正的连接吗?)而且它使得我能从这里做的事情非常有限。
例如,如果我想限制一个地址(对于oneToOne关系)而不影响oneToMany数据库关系。我如何修改此SQL来做到这一点?
这是一个最好的想法甚至可以用一个查询吗?
答案 0 :(得分:1)
无需对您当前的查询进行分组:
SELECT
`User`.`id` AS `User_id`, `User`.`name` AS `User_name`,
`Address`.`id` AS `Address_id`, `Address`.`address` AS `Address_address`, `Address`.`user_id` AS `Address_user_id`,
`Database`.`id` AS `Database_id`, `Database`.`user_id` AS `Database_user_id`
FROM `users` AS `User`,
JOIN `addresses` AS `Address` ON `Address`.`user_id` = `User`.`id`
JOIN `databases` AS `Database` ON `Database`.`user_id` = `User`.`id`
WHERE `User`.`id` = 1;
要获得一个用户记录,您需要找到一种方法来逻辑限制您的地址和您根据应用程序的要求检索的数据库记录(使用MAX或其他聚合函数),或者只是对它们进行分组,以便以后通过应用程序进行解析,例如:
SELECT
`User`.`id` AS `User_id`, `User`.`name` AS `User_name`,
GROUP_CONCAT(CONCAT(`Address`.`id`, ',', `Address`.`address`, ',', `Address`.`user_id`) SEPARATOR '|') AS `Addresses`
GROUP_CONCAT(CONCAT(`Database`.`id`, ',', `Database`.`user_id`) SEPARATOR '|') AS `Databases`
FROM `users` AS `User`,
JOIN `addresses` AS `Address` ON `Address`.`user_id` = `User`.`id`
JOIN `databases` AS `Database` ON `Database`.`user_id` = `User`.`id`
WHERE `User`.`id` = 1
GROUP BY `User`.`id`;
注意GROUP_CONCAT的限制(默认情况下为1024个字符,但可配置)...仅在此处使用它。
编辑:您应该从上面的示例中获得的另一点是永远不要使用HAVING子句,您可以使用WHERE子句来执行相同的操作。在哪里明显更快。仅使用HAVING子句来测试聚合操作的结果。