简体   繁体   English

对于左联接和分组依据,MYSQL COUNT不返回0

[英]MYSQL COUNT not returning 0 for Left Join and Group By

I am simply trying to get the code below to recognize when the count is zero and return 0. 我只是想让下面的代码识别计数为零并返回0。

Setting the date variables and week numbers table 设置日期变量和星期数表

//set first of the year and today
  $year = date("Y");
  $start = "01/01/".$year;
  $today = date("Y-m-d");
  $first = $year."-01-01";
  $start = $year."-01-01";

  $date1 = new DateTime($first);
  $date2 = new DateTime($today);
  $interval = $date1->diff($date2);

  $weeks = floor(($interval->days) / 7);

  //create weeks table
    $sql = "DROP TEMPORARY TABLE IF EXISTS weekstbl" ;
    mysqli_query ($db, $sql ) or ( "Error " . mysqli_error () ) ;

    $weekstbl = "
      CREATE TEMPORARY TABLE weekstbl (
        `weekNo` int NOT NULL,
        `weekStart` Date,
        `weekEnd` Date,
        PRIMARY KEY(weekNo)
      )
    ";

   mysqli_query($db, $weekstbl) or die ("Sql error : ".mysqli_error());

  for($i = 1; $i <= $weeks; $i++){    
      $week = $date1->format("W");
      $date1->add(new DateInterval('P6D'));
      $date1->format('Y-m-d');
      $newDate1 = $date1->format('Y-m-d');

      $statement = $db->prepare("INSERT INTO weekstbl (weekNo,weekStart,weekEnd) VALUES (?,?,?)");
      $statement->bind_param('iss', $week,$start,$newDate1);
      $statement->execute();

      $date1->add(new DateInterval('P1D'));
      $start = $date1->format('Y-m-d');
  }

This code outputs the all of the week numbers, start date for the week and end date for the week for the current year through the current day. 该代码输出当前年份到当前日期的所有星期数,星期的开始日期和星期的结束日期。 Looks like the following: 看起来如下:

------------------------------------
| weekNo |  weekStart |  weekEnd   |
------------------------------------
|   52   | 2017-01-01 | 2017-01-07 |
|    1   | 2017-01-08 | 2017-01-14 |
|    2   | 2017-01-15 | 2017-01-21 |

This continues on through the current date the system is being accessed. 从访问系统的当前日期一直持续到现在。 This will then be used to join with another few other tables with conditions. 然后,它将用于与其他一些有条件的其他表联接。 This is what I expect to be returned but in all of my trials listed below, I cannot accomplish this. 这是我希望返回的结果,但是在下面列出的所有试验中,我都无法完成。 I ran this when there were 12 weeks in the current Year, which means there should be 12 numbers following the name. 我在当年有12个星期时运行此程序,这意味着名称后应有12个数字。

[["Ryan Balcom",3,30,3,1,10,0,1,2,5,1,3,3],["Jared Beckwith",40,8,13,8,13,7,5,3,11,5,3,1],["Jim Roberts",0,32,8,7,2,9,4,2,8,4,4,10],["Jim Kelly",44,24,12,14,14,16,10,25,12,8,7,6],["Josh Bell",34,10,10,5,9,8,5,23,7,6,6,14],["Rick Zuniga",0,0,0,0,0,3,1,1,0,0,0,0],["Mike Horton",37,20,7,10,16,5,6,4,5,3,5,1],["Paul Schilthuis",31,11,9,2,8,6,4,0,5,9,8,4],["TJ Sutton",1,10,0,0,0,0,0,0,0,0,0,0]]

Trial 1 试验1

    $assignments = "
SELECT COUNT(j.leadid) AS leadcount, u.username
  FROM weekstbl wk
  LEFT JOIN jobbooktbl j
    ON wk.weekNo=WEEK(j.leadcreated)
  LEFT JOIN assignmentstbl a
    ON j.leadid=a.custid
  LEFT JOIN usertbl u
    ON a.userid=u.userid
  WHERE j.leadcreated >= '".$first."' AND j.leadcreated <= '".$today."' AND YEAR(j.leadcreated) = '".$year."'
  GROUP BY WEEK(j.leadcreated), a.userid";
    $assignmentsqry = mysqli_query($db,$assignments);
    while ($row = mysqli_fetch_array($assignmentsqry)) {
      $key = $row['username']; //unnecessary variable for demonstration purposes
      if (!isset($volumeYTDsm[$key])) {
        $volumeYTDsm[$key] = [$row['username']];
      }
      $float = floatval($row['leadcount']);
        $volumeYTDsm[$key][] = $float;
      }
      $volumeYTDsm = array_values($volumeYTDsm);//removing keys
    }

This outputs the above but does not inlcude the 0 weeks: 输出上述内容,但不包括0周:

[["Ryan Balcom",3,30,3,1,10,1,2,5,1,3,3],["Jared Beckwith",40,8,13,8,13,7,5,3,11,5,3,1],["Jim Roberts",32,8,7,2,9,4,2,8,4,4,10],["Jim Kelly",44,24,12,14,14,16,10,25,12,8,7,6],["Josh Bell",34,10,10,5,9,8,5,23,7,6,6,14],["Rick Zuniga",3,1,1],["Mike Horton",37,20,7,10,16,5,6,4,5,3,5,1],["Paul Schilthuis",31,11,9,2,8,6,4,5,9,8,4],["TJ Sutton",1,10]]

Trial 2 试用2

$assignments = "
  SELECT COUNT(*) AS leadcount, u.username
    FROM weekstbl wk
    LEFT OUTER JOIN jobbooktbl j
      ON (wk.weekNo=WEEK(j.leadcreated)) AND j.leadcreated >= '".$first."' AND j.leadcreated <= '".$today."' AND YEAR(j.leadcreated) = '".$year."'
    LEFT JOIN assignmentstbl a
      ON j.leadid=a.custid
    LEFT JOIN usertbl u
      ON a.userid=u.userid
    GROUP BY wk.weekNo, a.userid";

This outputs the following...not really sure what this is outputting with the null name: 这将输出以下内容...不确定使用空名称输出的内容:

[[null,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],["Ryan Balcom",3,30,3,1,10,1,2,5,1,3,3],["Jared Beckwith",40,8,13,8,13,7,5,3,11,5,3,1],["Jim Roberts",32,8,7,2,9,4,2,8,4,4,10],["Jim Kelly",44,24,12,14,14,16,10,25,12,8,7,6],["Josh Bell",34,10,10,5,9,8,5,23,7,6,6,14],["Rick Zuniga",3,1,1],["Mike Horton",37,20,7,10,16,5,6,4,5,3,5,1],["Paul Schilthuis",31,11,9,2,8,6,4,5,9,8,4],["TJ Sutton",1,10]]

With both of these methods I have tried to include COALESCE and IFNULL but neither changed the result for either query: 使用这两种方法,我都试图包括COALESCE和IFNULL,但是都没有改变任何一个查询的结果:

COALESCE(COUNT(j.leadid),0) AS leadcount
IFNULL(COUNT(j.leadid),0) AS leadcount

I have been trying to figure this out for a month and nothing I throw at it seems to work. 我一直在努力解决这个问题一个月,但似乎没有任何投入。 Any assistance or direction would be greatly appreciated! 任何帮助或指示将不胜感激!

You need to add a column from the primary table to your group by, otherwise you are grouping by values that only exist in one of your left joins. 您需要将主表中的一列添加到分组依据,否则,您将按仅存在于您的左联接之一中的值进行分组。

SELECT 
    COUNT(j.leadid) AS leadcount, 
    IF(u.username IS NULL,'NOT FOUND',u.username) AS username
FROM weekstbl wk
LEFT JOIN jobbooktbl j
    ON wk.weekNo=WEEK(j.leadcreated)
LEFT JOIN assignmentstbl a
    ON j.leadid=a.custid
  LEFT JOIN usertbl u
    ON a.userid=u.userid
  WHERE (j.leadcreated >= '".$first."' AND 
        j.leadcreated <= '".$today."' AND 
        YEAR(j.leadcreated) = '".$year."') OR
        j.leadcreated IS NULL
  GROUP BY wk.weekno, WEEK(j.leadcreated), a.userid
  ORDER BY wk.weekStart

A better where clause would compare to the date in weekstbl . 更好的where子句将与weekstbl的日期进行weekstbl

The condition in the WHERE is turning the first LEFT JOIN into an inner join. WHERE的条件是将第一个LEFT JOIN变成一个内部LEFT JOIN So, you would seem to want: 因此,您似乎想要:

SELECT COUNT(j.leadid) AS leadcount, u.username
FROM weekstbl wk LEFT JOIN
     jobbooktbl j
     ON wk.weekNo = WEEK(j.leadcreated) AND
        j.leadcreated >= '".$first."' AND j.leadcreated <= '".$today."' AND
        YEAR(j.leadcreated) = '".$year."'LEFT JOIN
     assignmentstbl a
     ON j.leadid = a.custid LEFT JOIN
     usertbl u
     ON a.userid = u.userid
GROUP BY WEEK(j.leadcreated), a.userid;

However, you are aggregating by the week, but not including the week in the SELECT . 但是,您按星期进行汇总,但不包括SELECT的星期。 I suspect that you want: 我怀疑您想要:

SELECT wk.weekNo, u.username, COUNT(j.leadid) AS leadcount
FROM weekstbl wk LEFT JOIN
     jobbooktbl j
     ON wk.weekNo = WEEK(j.leadcreated) AND
        j.leadcreated >= '".$first."' AND j.leadcreated <= '".$today."' AND
        YEAR(j.leadcreated) = '".$year."'LEFT JOIN
     assignmentstbl a
     ON j.leadid = a.custid LEFT JOIN
     usertbl u
     ON a.userid = u.userid
GROUP BY wk.weekNo, a.userid;

You don't want to aggregate by WEEK(j.leadcreated) because that might be NULL . 您不希望通过WEEK(j.leadcreated)进行聚合,因为这可能为NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM