无法基于两个条件两次加入同一个表

时间:2017-05-19 20:32:27

标签: mysql left-join

我在PHP中使用MySQL。以下是我收到错误的查询。

$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 个答案:

答案 0 :(得分: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

没有正确的FROM子句。这是数据库查看的第一部分,因此它知道它从何处获取数据以及它如何连接在一起。您的表别名在此处设置,然后在查询中的其他地方使用。这导致你遇到第二个问题。

您在SELECT子句中引用myDataTable,但是当数据库查看您的SELECT myDataTable时,不会在上下文中引用n1。别名n2SELECT 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 两次:

public class CorteConVentas
{
    public Dictionary<string, List<Gasto>> dictaGastosAgrupada { get; set; }
}