Переписывание MySQL-запроса с подзапросами в соединения

Я написал довольно сложный запрос SQL, чтобы получить некоторую статистику о животных из базы данных выборки животных. Этот запрос включает ряд подзапросов, и теперь я хотел бы посмотреть, можно ли каким-либо образом переписать этот запрос, чтобы использовать соединения вместо подзапросов. У меня смутное представление, что это может сократить время запроса. (сейчас около 23 секунд на Mac mini).

Вот вопрос:

SELECT COUNT(DISTINCT a.AnimalID), TO_DAYS(a.VisitDate) AS day, 
   DATE_FORMAT(a.VisitDate, '%b %d %Y'), a.origin, 
   (
    SELECT COUNT(DISTINCT a.AnimalID)
           FROM samples AS a 
                JOIN
                custom_animals AS b 
                ON a.AnimalID = b.animal_id
                WHERE
                     b.organism = 2
                     AND
                         TO_DAYS(a.VisitDate) = day
    ) AS Goats, 
    (
     SELECT COUNT(DISTINCT a.AnimalID) 
            FROM samples AS a 
                 JOIN custom_animals AS b 
                 ON a.AnimalID = b.animal_id 
                 WHERE
                      b.organism = 2
                      AND 
                         b.sex = 'Female'
                      AND
                         TO_DAYS(a.VisitDate) = day
    ) AS GF,
    (
     SELECT COUNT(DISTINCT a.AnimalID) 
            FROM samples AS a 
                 JOIN custom_animals AS b 
                 ON a.AnimalID = b.animal_id 
                 WHERE 
                      b.organism = 3
                      AND
                         b.sex = 'Female'
                      AND
                         TO_DAYS(a.VisitDate) = day
    ) AS SF
    FROM
        samples AS a 
        JOIN custom_animals AS b 
        ON a.AnimalID = b.animal_id 
        WHERE
             project = 5
             AND
                AnimalID LIKE 'AVD%'
        GROUP BY
                TO_DAYS(a.VisitDate);

Благодаря ksogor мой запрос теперь выполняется быстрее:

SELECT  DATE_FORMAT(s.VisitDate, '%b %d %Y') AS date,
    s.origin,
    SUM(IF(project = 5 AND s.AnimalID LIKE 'AVD%', 1, 0)) AS sampled_animals, 
    SUM(IF(ca.organism = 2, 1, 0)) AS sampled_goats,
    SUM(IF(ca.organism = 2 AND ca.sex = 'Female', 1, 0)) AS female_goats,
    SUM(IF(ca.organism = 3 AND ca.sex = 'Female', 1, 0)) AS female_sheep
FROM samples s JOIN custom_animals ca ON s.AnimalID = ca.animal_id
GROUP BY date;

Мне все равно нужно было бы сделать этот запрос select отличным s.AnimalID, хотя сейчас он подсчитывает образцы, взятые у этих животных вместо самих животных. У кого-нибудь есть идеи?


После дополнительной помощи от ksogor у меня появился отличный вопрос:

SELECT  DATE_FORMAT(s.VisitDate, '%b %d %Y') AS date,
    s.origin,
    SUM(IF(project = 5 AND s.AnimalID LIKE 'AVD%', 1, 0)) AS sampled_animals, 
    SUM(IF(ca.organism = 2, 1, 0)) AS sampled_goats,
    SUM(IF(ca.organism = 2 AND ca.sex = 'Female', 1, 0)) AS female_goats,
    SUM(IF(ca.organism = 3 AND ca.sex = 'Female', 1, 0)) AS female_sheep
FROM (
    SELECT DISTINCT AnimalID AS AnimalID,
           VisitDate,
           origin,
           project
           FROM samples
) s 
JOIN custom_animals ca ON s.AnimalID = ca.animal_id
GROUP BY date;
1
задан Community 23 May 2017 в 11:56
поделиться