Php SQL嵌套选择修复

Php SQL嵌套选择修复,php,mysql,sql,Php,Mysql,Sql,我有两张表,小时和天,小时存储一个专业人员一天的可用小时数。 天,存储保留的时间 表4小时 id | begin | end | profesional 1 | 09:00 | 10:00 | 1 2 | 10:00 | 11:00 | 1 3 | 11:00 | 12:00 | 1 4 | 13:00 | 14:00 | 1 5 | 14:00 | 15:00 | 1 6 | 09:30 | 10:30 | 2

我有两张表,小时和天,小时存储一个专业人员一天的可用小时数。 天,存储保留的时间

表4小时

id  | begin   | end    | profesional 
1   | 09:00   |  10:00 | 1 
2   | 10:00   |  11:00 | 1 
3   | 11:00   |  12:00 | 1 
4   | 13:00   |  14:00 | 1 
5   | 14:00   |  15:00 | 1 
6   | 09:30   |  10:30 | 2 
7   | 13:00   |  14:30 | 2 
8   | 14:30   |  15:30 | 2 
id  | day_id  | begin   | end    | profesional 
1   | 1       | 09:00   |  10:00 | 1 
2   | 2       | 10:00   |  11:00 | 1 
3   | 1       | 11:00   |  12:00 | 1 
4   | 3       | 13:00   |  14:00 | 1 
5   | 3       | 14:00   |  15:00 | 1 
6   | 1       | 09:30   |  10:30 | 2 
7   | 2       | 13:00   |  14:30 | 2 
8   | 2       | 14:30   |  15:30 | 2 
表10天

id  | hour_id | day
1  | 1        |20151201 
2  | 3        |20151201 
3  | 6        |20151201 
4  | 2        |20151205 
5  | 7        |20151205 
6  | 8        |20151205
id  | day
1   | 20151201 
2   | 20151205 
一、 尝试了以下查询,但不起作用

SELECT *, (SELECT day from days where hours.id = days.hours_id and day = '20151201') as 'day' 
FROM hours 
where profesional = 1 
因此,我想有所有的结果,从专业和一个日期刚好匹配如下

表2结果

id  | begin | end    | profesional | day
1   | 09:00 |  10:00 | 1           |20151201
2   | 10:00 |  11:00 | 1           |NULL
3   | 11:00 |  12:00 | 1           |20151201
4   | 13:00 |  14:00 | 1           |NULL
5   | 14:00 |  15:00 | 1           |NULL

使用
LEFT JOIN
获取第一个表中的所有行,当没有匹配行时,在第二个表的列中返回
NULL

SELECT h.*, d.day
FROM hours AS h
LEFT JOIN days AS d ON h.id = d.hours_id AND d.day = '20151201'
WHERE h.profesional = 1

使用
LEFT JOIN
获取第一个表中的所有行,当没有匹配行时,在第二个表的列中返回
NULL

SELECT h.*, d.day
FROM hours AS h
LEFT JOIN days AS d ON h.id = d.hours_id AND d.day = '20151201'
WHERE h.profesional = 1

我想,你已经从其他答案中得到了答案。但我只想指出另一件事,您的数据库设置错误。不要将
hour\u id
保留在
days
表中,而是将
day\u id
保留在
hours
表中。它应该减少数据库中的行数,并从长远来看帮助您节省存储空间。所以它可以是这样的:

表4小时

id  | begin   | end    | profesional 
1   | 09:00   |  10:00 | 1 
2   | 10:00   |  11:00 | 1 
3   | 11:00   |  12:00 | 1 
4   | 13:00   |  14:00 | 1 
5   | 14:00   |  15:00 | 1 
6   | 09:30   |  10:30 | 2 
7   | 13:00   |  14:30 | 2 
8   | 14:30   |  15:30 | 2 
id  | day_id  | begin   | end    | profesional 
1   | 1       | 09:00   |  10:00 | 1 
2   | 2       | 10:00   |  11:00 | 1 
3   | 1       | 11:00   |  12:00 | 1 
4   | 3       | 13:00   |  14:00 | 1 
5   | 3       | 14:00   |  15:00 | 1 
6   | 1       | 09:30   |  10:30 | 2 
7   | 2       | 13:00   |  14:30 | 2 
8   | 2       | 14:30   |  15:30 | 2 
表10天

id  | hour_id | day
1  | 1        |20151201 
2  | 3        |20151201 
3  | 6        |20151201 
4  | 2        |20151205 
5  | 7        |20151205 
6  | 8        |20151205
id  | day
1   | 20151201 
2   | 20151205 
现在像这样更改SQL

SELECT h.*, d.day
FROM hours AS h
LEFT JOIN days AS d ON h.day_id = d.id AND d.day = '20151201'
WHERE h.profesional = 1

我想,你已经从其他答案中得到了答案。但我只想指出另一件事,您的数据库设置错误。不要将
hour\u id
保留在
days
表中,而是将
day\u id
保留在
hours
表中。它应该减少数据库中的行数,并从长远来看帮助您节省存储空间。所以它可以是这样的:

表4小时

id  | begin   | end    | profesional 
1   | 09:00   |  10:00 | 1 
2   | 10:00   |  11:00 | 1 
3   | 11:00   |  12:00 | 1 
4   | 13:00   |  14:00 | 1 
5   | 14:00   |  15:00 | 1 
6   | 09:30   |  10:30 | 2 
7   | 13:00   |  14:30 | 2 
8   | 14:30   |  15:30 | 2 
id  | day_id  | begin   | end    | profesional 
1   | 1       | 09:00   |  10:00 | 1 
2   | 2       | 10:00   |  11:00 | 1 
3   | 1       | 11:00   |  12:00 | 1 
4   | 3       | 13:00   |  14:00 | 1 
5   | 3       | 14:00   |  15:00 | 1 
6   | 1       | 09:30   |  10:30 | 2 
7   | 2       | 13:00   |  14:30 | 2 
8   | 2       | 14:30   |  15:30 | 2 
表10天

id  | hour_id | day
1  | 1        |20151201 
2  | 3        |20151201 
3  | 6        |20151201 
4  | 2        |20151205 
5  | 7        |20151205 
6  | 8        |20151205
id  | day
1   | 20151201 
2   | 20151205 
现在像这样更改SQL

SELECT h.*, d.day
FROM hours AS h
LEFT JOIN days AS d ON h.day_id = d.id AND d.day = '20151201'
WHERE h.profesional = 1

请仔细阅读。@PraveenKumar这样做真的使表更容易阅读吗?@Barmar我正在重写boss。请仔细阅读。@PraveenKumar这样做真的使表更容易阅读吗?@Barmar我正在重写boss。对于不匹配的行,
内部联接
不会显示
NULL
。已编辑,谢谢。还有一件事我不太确定,在我的WHERE子句中,我需要提到像table_day.day='20151201'这样的表的名称吗?或者它按原样工作吗?只有在列名不明确的情况下。当使用
LEFT JOIN
时,需要将
day
测试放在
ON
子句中。否则它将不会显示
day=NULL
的行。我还喜欢使用表名来让读者清楚,即使名称没有歧义。但我也喜欢指定短表名别名。
内部联接
不会为不匹配的行显示
NULL
。编辑,谢谢。还有一件事我不确定,在我的WHERE子句中,我是否需要提及像table_day.day='20151201'这样的表的名称,或者它是按原样工作的?仅当列名不明确时。当使用
LEFT JOIN
时,需要将
day
测试放在
ON
子句中。否则它将不会显示
day=NULL
的行。我还喜欢使用表名来让读者清楚,即使名称没有歧义。但我也喜欢指定短表名别名。