左连接意外结果所有日期,对于所有项目计数

时间:2017-11-03 17:58:31

标签: mysql left-join

我正在撰写一份报告,基本上我想回复所有已经或没有预订的学校的日期。

通常我会使用左连接和一个子查询来处理我需要的每个级别的数据。

案件是它没有按预期工作,我不确定我是否可能遗漏某些东西或什么,但经过数小时的测试我决定寻求帮助!

这是小提琴:

http://sqlfiddle.com/#!9/5e9279/5

预期结果应为:

public function loanset($debitid, $creditid)
{
    $debit_user= UserModel::findOrFail($debitid);
    $credit_user= UserModel::findOrFail($creditid);
    return view('load.add',compact('debit_user','credit_user'));
}

等。

但正如小提琴所示,我得到了不同的东西。例如,当我从子查询中获取它时,school_name永远不应为null。

这是我在sqlfiddle中得到的,我简化了整个查询只是为了演示这个问题。

enter image description here

使用的架构:

on_date     school_name     COALESCE(xx.cnt,0)
2016-02-01  school 1    1
2016-02-01  school 2    0
2016-02-01  school 3    0
2016-02-01  school 4    0
2016-02-01  school 5    0
2016-02-02  school 1    0
2016-02-02  school 2    0
2016-02-02  school 3    0
2016-02-02  school 4    0
2016-02-02  school 5    0
2016-02-03  school 1    0
2016-02-03  school 2    1
2016-02-03  school 3    0
2016-02-03  school 4    0
2016-02-03  school 5    0

查询:

create table tbl_school (
  school_id int auto_increment primary key,
  school_name varchar(255)
  );

create table tbl_school_booking (
    school_booking_id int auto_increment primary key,
    school_id int,
    booked_date date
);

create table tbl_calendar(
 calendar_date date
);

insert into tbl_school (school_name) values ('school 1'),('school 2'),('school 3'),('school 4'),('school 5');
insert into tbl_school_booking (school_id, booked_date) values (1,'2016-02-01'),(2,'2016-02-03'),(3,'2016-02-07');

insert into tbl_calendar (calendar_date) values ('2016-02-01'),('2016-02-02'), ('2016-02-03'),('2016-02-04'), 
('2016-02-05'),('2016-02-06'),('2016-02-07'),('2016-02-08'),('2016-02-09'),('2016-02-10'),('2016-02-11');

1 个答案:

答案 0 :(得分:1)

首先,您需要计算所有组合,然后您可以看到缺少的日期。

<强> SQL DEMO

SELECT s.school_id, c.calendar_date, COUNT(b.school_id)
FROM tbl_school s
CROSS JOIN tbl_calendar c
LEFT JOIN tbl_school_booking b
  ON s.school_id  = b.school_id
 AND c.calendar_date = b.booked_date
GROUP BY  s.school_id, c.calendar_date
;