【问题标题】:All Entries on Table 1 but only matching entires on table 2 where table 2 contains where statement表 1 中的所有条目,但仅匹配表 2 中的条目,其中表 2 包含 where 语句
【发布时间】:2018-10-14 04:57:19
【问题描述】:

我在加入以下表格时遇到问题,表 1 包含所有专家,即

约翰 (id1)
皮特 (id2)
哈利 (id3)
乔安妮(id4)
等等

仅当专家在某一天有空时才会填充表 2,即

id1 2018-10-19
id3 2018-10-19

当我使用 where 语句 table2.date=2018-10-19 时我需要从 MySQL 查询得到的结果是

约翰 2018-10-19
皮特
哈利 2018-10-19
乔安妮

但我真正得到的是

约翰 2018-10-19
哈利 2018-10-19

这是正确的,但我需要所有专家按顺序展示。

谁能帮忙提点建议

【问题讨论】:

  • 嗨。请阅读How to Ask 并采取行动(尤其是关于作业),点击谷歌搜索“stackexhange 作业”和向下投票箭头鼠标悬停文本。这是一个微不足道的常见问题解答。请始终在谷歌上搜索您的问题/问题/目标的许多清晰、简洁和特定的版本/措辞,带和不带您的特定字符串/名称,并阅读许多答案。将您发现的相关关键字添加到搜索中。如果您没有找到答案,请发布,使用 1 个变体搜索作为标签的标题和关键字。请参阅向下投票箭头鼠标悬停文本。如果您确实有一个不重复的代码问题要发布,请阅读并在minimal reproducible example 上采取行动。
  • '按顺序显示' - 什么名字,id?顺便说一句,我怀疑您使用的是内部联接而不是左联接,如果没有看到您的查询就很难分辨。
  • 按专业名称排序。我尝试了几个查询,包括 SELECT * from clinitions LEFT OUTER JOIN availability ON clinitions.cID = availability.aClinition WHERE (availability.aClinition = clinitions.cID OR clinition.cID NOT EXIST) AND availability.aDate ='"&request.querystring(" d")&"'

标签: mysql join where


【解决方案1】:

除非您的问题不是一个好问题(我怀疑它可能是一个坏问题),否则您不需要 where 语句。所以

drop table if exists t1,t2;

create table t1 (id int,val varchar(10));
insert into t1 values
(1,'John' ),
(2,'Pete' ),
(3,'Harry'),
(4,'Joanne');

create table t2(t1id int,dt date);
insert into t2 values
(1 ,'2018-10-19'),
(3 ,'2018-10-19');

 SELECT * from t1
 LEFT OUTER JOIN t2 ON t1.id = t2.t1id
 order by t1.val;

结果

+------+--------+------+------------+
| id   | val    | t1id | dt         |
+------+--------+------+------------+
|    3 | Harry  |    3 | 2018-10-19 |
|    4 | Joanne | NULL | NULL       |
|    1 | John   |    1 | 2018-10-19 |
|    2 | Pete   | NULL | NULL       |
+------+--------+------+------------+
4 rows in set (0.00 sec)

如果您希望按名称值排序,我不知道如何在结果集中获得 johns,pete,harry,joanne。 而 '"&request.querystring("d")&"' 不是 mysql 这个 php 可能是什么?

如果您对特定日期的可用性或其他方面感兴趣,例如,您将首先交叉加入(创建笛卡尔积)专家到日期

select t1.id,t1.val,dt
 from t1
 cross join (select '2018-10-19' dt 
 #union all select '2018-10-20'
 ) s;
+------+--------+------------+
| id   | val    | dt         |
+------+--------+------------+
|    1 | John   | 2018-10-19 |
|    2 | Pete   | 2018-10-19 |
|    3 | Harry  | 2018-10-19 |
|    4 | Joanne | 2018-10-19 |
+------+--------+------------+
4 rows in set (0.00 sec)

然后看看它们是否存在于table2中

select t.id,t.val,t.dt tdt , ifnull(t2.dt,'Not Available') t2dt
 from 
 (select t1.id,t1.val,dt
 from t1
 cross join (select '2018-10-19' dt 
 #union all select '2018-10-20'
 ) s
 ) t 
 left join t2
 on t.id = t2.t1id and t2.dt = t.dt
 order by t.dt,val;

+------+--------+------------+---------------+
| id   | val    | tdt        | t2dt          |
+------+--------+------------+---------------+
|    3 | Harry  | 2018-10-19 | 2018-10-19    |
|    4 | Joanne | 2018-10-19 | Not Available |
|    1 | John   | 2018-10-19 | 2018-10-19    |
|    2 | Pete   | 2018-10-19 | Not Available |
+------+--------+------------+---------------+

请注意,您可以使用联合在交叉连接中包含任意数量的日期。我已将 2018-10-20 注释掉。

如果您的日期范围很大,联合可能会变得笨拙,在您的数据库中创建日历/日期表可能很有用,您可以在交叉连接中替换它。例如

select t.id,t.val,t.dt tdt , ifnull(t2.dt,'Not Available') t2dt
 from 
 (select t1.id,t1.val,dt
 from t1
 cross join (select dte dt from dates where dte between '2018-10-19' and '2018-10-19' 
 ) s
 ) t 
 left join t2
 on t.id = t2.t1id and t2.dt = t.dt
 order by t.dt,val;

您当然可以将交叉连接条件修改为您想要的任何内容。

【讨论】:

  • 嗨。感谢您不厌其烦地这样做。回想起来,我应该更详细地解释一下。需要 where 语句,因为我只想从 t2 'WHERE the date = xxx' (在本例中为 2018-10-19)获取结果,但如最初所述,从 t1 获取所有名称,即使它们没有在 t2 中输入该日期。如果在您的示例中, t2 有多个日期,则所有记录都会显示。这解释得更好吗?你能提供更多帮助吗?非常感谢
  • @Tim White 编辑
  • 太棒了。非常感谢您的帮助。感谢您抽出宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 2015-07-18
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 2010-09-24
相关资源
最近更新 更多