1

目前,我正在为我的框架 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 来做到这一点?

这是一个查询的最佳主意吗?

4

1 回答 1

1

无需 GROUP 您当前的查询:

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 子句来做同样的事情。WHERE 明显更快。仅使用 HAVING 子句来测试聚合操作的结果。

于 2012-12-03T21:12:40.740 回答