Объединить результаты запроса, оптимизировать?

mysql, две таблицы:тест (один) и обзор(много).
Моя цель:из отзыва на одного в соответствующем номере

SELECT t.ID,t.TITLE,COALESCE(COUNT(r.ID),0) `count`
FROM `test` t 
LEFT OUTER JOIN review r
    ON t.ID = r.REVIEW_OBJ_ID 
WHERE r.REVIEW_TYPE = '4'
ORDER BY `count` DESC;

Выход:

ID                                  TITLE      count
402884f657e0a6d20157e0a82cc90000    brother    2

тестовая таблица (небольшая часть данных)

SELECT t.ID,t.TITLE
FROM `test` t;

Выход:

ID                                  TITLE
40284c8157ad8e7d0157ad8f86880000    1234567890123456789012345
402884f657e0a6d20157e0a82cc90000    brother
402884f657e0a6d20157e11967a20036    fg
402884f657e51eff0157e54cd8610004    AAA
402884f657e652fb0157e65642750000    BBB
0000000057f4dc900157f4ea9edd0000    VVV
00000000580065c5015800746d750000    CCC
00000000580065c501581d9f04f0000b    TTT

И я хочу получить это:

ID                                  TITLE                      count 
402884f657e0a6d20157e0a82cc90000    brother                    2
402884f657e652fb0157e65642750000    BBB                        0
00000000580065c501581d9f04f0000b    TTT                        0
402884f657e0a6d20157e11967a20036    fg                         0
0000000057f4dc900157f4ea9edd0000    VVV                        0
40284c8157ad8e7d0157ad8f86880000    1234567890123456789012345  0
402884f657e51eff0157e54cd8610004    AAA                        0
00000000580065c5015800746d750000    CCC                        0

Итак, я попробовал это, и это сработало:

SELECT t.ID,t.TITLE, COALESCE(r.c,0) `count`
FROM `test` t 
LEFT OUTER JOIN
(
    SELECT r.REVIEW_OBJ_ID obj_id, COUNT(r.ID) c 
    FROM review r,`test` t
    WHERE r.REVIEW_TYPE = '4' 
        AND t.ID = r.REVIEW_OBJ_ID
) r ON r.obj_id = t.ID
ORDER BY `count` DESC;

Но у меня есть два вопроса:

  1. Он чувствует, что я могу использовать один раз выбрать,чтобы узнать результат, но я использую два раза выбрать.Можно ли его оптимизировать?
  2. Добавьте a count(redundant) в поля тестовой таблицы, если это лучший выбор.

/REVIEW_TYPE и REVIEW_OBJ_ID решают, какой объект рассматривается, так же, как я использую «REVIEW_TYPE= ‘4’», чтобы связаться с testтаблицей/

drop table if exists user_doctor_review;
create table review
(
   ID                   varchar(64) not null,
   USER_ID              varchar(64),
   DOCTOR_ID            varchar(64),
   REVIEW_TYPE          varchar(1),
   REVIEW_OBJ_ID        varchar(64),
   SERVICE_SCORE        int(6),
   REVIEW_CONTENT       varchar(600),
   REVIEW_TIME          datetime,
   POID                 varchar(64),
   IS_ANONYMITY         varchar(1),
   CHECKED_STATUS       varchar(1),
   STATUS               varchar(1),
   REPLY_CONTENT        varchar(600),
   REPLY_TIME           datetime,
   DOCTOR_IS_READ       varchar(1),
   primary key (ID)
);

1 ответ

  1. Да, вы можете сделать это с помощью одной SELECTинструкции с этим запросом

    SELECT test.ID, test.TITLE, count(review.ID) as count from test
    left join review on test.ID = review.REVIEW_OBJ_ID
    where review.REVIEW_TYPE = 4 or review.ID is null
    group by test.ID
    

    Я создал скрипку SQL здесь: http://sqlfiddle.com/#!9 / c6a178 / 15

    Объяснение:
    Ключевыми моментами являются:

    or review.ID is null
    

    потому что это сделает запрос перечислить тесты без обзоров, и

    group by test.ID
    

    это позволит получить правильные подсчеты проверки, связанные с тестом.

    Результаты:

    ID                                  TITLE                       count
    --------------------------------    -------------------------   -----
    0000000057f4dc900157f4ea9edd0000    VVV                         0
    00000000580065c5015800746d750000    CCC                         0
    00000000580065c501581d9f04f0000b    TTT                         1
    40284c8157ad8e7d0157ad8f86880000    1234567890123456789012345   0
    402884f657e0a6d20157e0a82cc90000    brother                     2
    402884f657e0a6d20157e11967a20036    fg                          0
    402884f657e51eff0157e54cd8610004    AAA                         0
    402884f657e652fb0157e65642750000    BBB                         0