Невозможно присоединиться к одной и той же таблице дважды на основе двух условий

Я использую MySQL с PHP. Вот мой запрос, по которому я получаю ошибку.

$query = 
"SELECT days.day, count(myDataTable.appId) as countf, count(myDataTable.appId) as counts
            FROM
              (
               select curdate() as day
               union select curdate() - interval 1 day
               union select curdate() - interval 2 day
               union select curdate() - interval 3 day
               union select curdate() - interval 4 day
               union select curdate() - interval 5 day
               union select curdate() - interval 6 day
               union select curdate() - interval 7 day
               union select curdate() - interval 8 day
               union select curdate() - interval 9 day
               ) days
              left join myDataTable as n1
              on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
              group by days.day
              left join myDataTable as n2
              on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
              group by days.day";

Журнал ошибок:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near  'left join myDataTable on days.day = myDataTable.date AND myDataTable.appId ' at line 17

1 ответ

Решение

Это помогает правильно сделать отступ в вашем SQL, чтобы вы могли определить ошибки. Отступ по основным ключевым словам (SELECT, FROM, WHERE, HAVING, GROUP BY и ORDER BY) поможет вам быстро определить их:

SELECT 
    days.day, 
    count (myDataTable.appId) as countf, 
    count(myDataTable.appId) as counts
FROM
  (
     select curdate() as day
       union select curdate() - interval 1 day
       union select curdate() - interval 2 day
       union select curdate() - interval 3 day
       union select curdate() - interval 4 day
       union select curdate() - interval 5 day
       union select curdate() - interval 6 day
       union select curdate() - interval 7 day
       union select curdate() - interval 8 day
       union select curdate() - interval 9 day
   ) days
  left join myDataTable as n1
       on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
group by
  days.day
  left join myDataTable as n2
       on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
  days.day

Вы можете видеть, что у вас есть два GROUP BY, которые не будут работать. Кроме того, у вас есть LEFT JOIN тусоваться в первом GROUP BY пункт, который тоже не работает. Удаление этого первого GROUP BY ближе к вам

SELECT 
    days.day, 
    count (myDataTable.appId) as countf, 
    count(myDataTable.appId) as counts
FROM
  (
     select curdate() as day
       union select curdate() - interval 1 day
       union select curdate() - interval 2 day
       union select curdate() - interval 3 day
       union select curdate() - interval 4 day
       union select curdate() - interval 5 day
       union select curdate() - interval 6 day
       union select curdate() - interval 7 day
       union select curdate() - interval 8 day
       union select curdate() - interval 9 day
   ) days
  left join myDataTable as n1
       on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
  left join myDataTable as n2
       on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
  days.day

Нет, у вас есть правильное предложение ОТ. Это первая часть вашей базы данных, поэтому она знает, откуда она получает свои данные и как она объединяется. Ваши псевдонимы таблиц задаются здесь и затем используются ВЕЗДЕ где-либо еще в запросе. Что приводит вас ко второй проблеме.

Вы ссылаетесь myDataTable в вашем предложении SELECT, но к тому времени, когда база данных смотрит на ваш SELECTmyDataTable не в контексте. Псевдонимы n1 а также n2 хотя, поэтому измените их, чтобы ссылаться на псевдонимы вашей таблицы:

SELECT 
    days.day, 
    count (n1.appId) as countf, 
    count(n2.appId) as counts
FROM
  (
     select curdate() as day
       union select curdate() - interval 1 day
       union select curdate() - interval 2 day
       union select curdate() - interval 3 day
       union select curdate() - interval 4 day
       union select curdate() - interval 5 day
       union select curdate() - interval 6 day
       union select curdate() - interval 7 day
       union select curdate() - interval 8 day
       union select curdate() - interval 9 day
   ) days
  left join myDataTable as n1
       on days.day = n1.date AND n1.appId = '$id' AND n1.status = 'ERROR'
  left join myDataTable as n2
       on days.day = n2.date AND n2.appId = '$id' AND n2.status = 'SUCCESS'
group by
  days.day

Наконец, вместо того, чтобы присоединиться к myDataTable дважды для каждого статуса, вы можете использовать CASE утверждение в вашем SELECT:

SELECT 
    days.day,
    SUM(CASE WHEN n1.status = 'ERROR' THEN 1 ELSE 0 END) as countf,
    SUM(CASE WHEN n1.status = 'SUCCESS' THEN 1 ELSE 0 END) as counts    
FROM
  (
     select curdate() as day
       union select curdate() - interval 1 day
       union select curdate() - interval 2 day
       union select curdate() - interval 3 day
       union select curdate() - interval 4 day
       union select curdate() - interval 5 day
       union select curdate() - interval 6 day
       union select curdate() - interval 7 day
       union select curdate() - interval 8 day
       union select curdate() - interval 9 day
   ) days
  left join myDataTable as n1
       on days.day = n1.date AND n1.appId = '$id'  
group by
  days.day
Другие вопросы по тегам