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

それは問題なく機能しますが、おそらく最善の方法で行っていないことはわかっています (実際の結合を使用する必要がありますか?)。これにより、ここからできることは非常に制限されます。

たとえば、oneToMany データベースの関係に影響を与えずに (oneToOne の関係で) 1 つのアドレスに制限したい場合。それを行うには、この SQL をどのように変更しますか?

これは、1 つのクエリで実行するのに最適なアイデアですか?

4

1 に答える 1

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;

ユーザー レコードを 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 文字ですが、構成可能) に注意してください...ここでは例として使用します。

EDIT : 上記の例から取るべきもう 1 つの点は、WHERE 句を使用して同じことを行うことができる HAVING 句を決して使用しないことです。WHERE は大幅に高速です。集計操作の結果をテストするには、HAVING 句のみを使用してください。

于 2012-12-03T21:12:40.740 に答える