0

編集:コードを次のようにクリーンアップしましたが、まだ機能していません。左結合を使用しているにもかかわらず、 caregiver_reviewに一致 (c.id = cr.practice_id) が含まれている行のみが表示されます。

編集 2: ROUND & COUNT を削除すると、すべての行がビュー テーブルに正常に表示されるよりも、ROUND & COUNT などの SELECT 句で集計を使用することによって問題が発生していることがわかりました。両方を使用する必要がありますが、まだ解決策がわかりません。ROUND & COUNT を使用すると結果が変わる理由と、この問題を修正する方法を知っている人はいますか?

クエリは、view_caregiver というビュー (読み取り専用) テーブルからのものです。関連するテーブルは次のとおりです:
caregiver
address
caregiver_review

SELECT `c`.`id` AS `id`,`c`.`user_id` AS `user_id`,`c`.`address_id` AS `address_id`,`c`.`first_name` AS `first_name`,`c`.`last_name` AS `last_name`,`c`.`email` AS `email`,`c`.`phone` AS `phone`,`c`.`status_id` AS `status_id`,`c`.`summary` AS `summary`,`c`.`about` AS `about`,`c`.`business_name` AS `business_name`,`c`.`medical_experience` AS `medical_experience`,`c`.`traveling_distance` AS `traveling_distance`,`c`.`accepting_new_patients` AS `accepting_new_patients`,`a`.`address1` AS `address1`,`a`.`address2` AS `address2`,`a`.`city` AS `city`,`a`.`state_id` AS `address_state`,`a`.`latitude` AS `latitude`,`a`.`longitude` AS `longitude`, COUNT(DISTINCT `cr`.`id`) AS `rating_count`, ROUND((AVG((((`cr`.`rating_knowledge` + `cr`.`rating_personality`) + `cr`.`rating_office`) + `cr`.`rating_timeliness`)) / 2),0) AS `rating`
FROM caregiver AS c
LEFT JOIN address AS a ON (c.address_id = a.id)
LEFT JOIN caregiver_review AS cr ON (c.id = cr.practice_id)

これは機能しますが、 caregiver_reviewにpractice_idの一致が含まれている行のみが表示されます。caregiver_reviewの一致がない場合でも、 caregiverテーブルのすべての行を表示したいと考えています。これは LEFT JOIN で達成できることは知っていますが、なぜ機能しないのかわかりません!

4

2 に答える 2

2

あなたが抱えている問題は、集計関数を使用するときに GROUP BY がないことが原因だと思います。GROUP BY 関数がない場合、すべてのデータは返されません。

これを行うには 2 つの方法があります。サブクエリで集計し、単一の列で GROUP BY できます。

SELECT `c`.`id` AS `id`,`c`.`user_id` AS `user_id`,
  `c`.`address_id` AS `address_id`,`c`.`first_name` AS `first_name`,
  `c`.`last_name` AS `last_name`,`c`.`email` AS `email`,
  `c`.`phone` AS `phone`,`c`.`status_id` AS `status_id`,
  `c`.`summary` AS `summary`,`c`.`about` AS `about`,
  `c`.`business_name` AS `business_name`,
  `c`.`medical_experience` AS `medical_experience`,
  `c`.`traveling_distance` AS `traveling_distance`,
  `c`.`accepting_new_patients` AS `accepting_new_patients`,
  `a`.`address1` AS `address1`,`a`.`address2` AS `address2`,
  `a`.`city` AS `city`,`a`.`state_id` AS `address_state`,
  `a`.`latitude` AS `latitude`,`a`.`longitude` AS `longitude`, 
  cr.`rating_count`, 
  cr.`rating`
FROM caregiver AS c
LEFT JOIN address AS a 
  ON (c.address_id = a.id)
LEFT JOIN
(
  select cr.practice_id,
    COUNT(DISTINCT `cr`.`id`) AS `rating_count`,
    ROUND((AVG((((`cr`.`rating_knowledge` + `cr`.`rating_personality`) + `cr`.`rating_office`) + `cr`.`rating_timeliness`)) / 2),0) AS `rating`
  from caregiver_review AS cr
  GROUP BY cr.practice_id
) cr
  ON (c.id = cr.practice_id)

または、元のクエリを集計し、集計されていない SELECT リスト内の列に GROUP BY を適用できます。

SELECT `c`.`id` AS `id`,`c`.`user_id` AS `user_id`,
  `c`.`address_id` AS `address_id`,`c`.`first_name` AS `first_name`,
  `c`.`last_name` AS `last_name`,`c`.`email` AS `email`,
  `c`.`phone` AS `phone`,`c`.`status_id` AS `status_id`,
  `c`.`summary` AS `summary`,`c`.`about` AS `about`,
  `c`.`business_name` AS `business_name`,
  `c`.`medical_experience` AS `medical_experience`,
  `c`.`traveling_distance` AS `traveling_distance`,
  `c`.`accepting_new_patients` AS `accepting_new_patients`,
  `a`.`address1` AS `address1`,`a`.`address2` AS `address2`,
  `a`.`city` AS `city`,`a`.`state_id` AS `address_state`,
  `a`.`latitude` AS `latitude`,`a`.`longitude` AS `longitude`, 
  COUNT(DISTINCT `cr`.`id`) AS `rating_count`, 
  ROUND((AVG((((`cr`.`rating_knowledge` + `cr`.`rating_personality`) + `cr`.`rating_office`) + `cr`.`rating_timeliness`)) / 2),0) AS `rating`
FROM caregiver AS c
LEFT JOIN address AS a 
  ON (c.address_id = a.id)
LEFT JOIN caregiver_review AS cr
  ON (c.id = cr.practice_id)
GROUP BY `c`.`id`, `c`.`user_id`, `c`.`address_id`, `c`.`first_name`
  , `c`.`last_name`, `c`.`email`, `c`.`phone`, `c`.`status_id`
  , `c`.`summary`, `c`.`about`, `c`.`business_name`, `c`.`medical_experience`
  , `c`.`traveling_distance`, `c`.`accepting_new_patients`
  , `a`.`address1`, `a`.`address2`, `a`.`city`, `a`.`state_id`
  , `a`.`latitude`, `a`.`longitude`
于 2013-05-29T21:05:33.977 に答える
0

やってみました...

select c.id, a.address_id, cr.practice_id
from caregiver as c
left join address as a on ( c.address_id = a.id )
left join caregiver_review as cr on ( c.id = cr.practice_id )
于 2013-05-23T22:41:15.997 に答える