我有一种奇怪的情况。我还没有找到解决方案。我尝试过使用各种连接和子查询,所以我要求一些帮助。我正在使用MySQLi和PHP 7。
我有两张桌子。一个表(称为表)包含人员列表。另一个表包含该人已完成的数据日志,称为报告。
我可以毫无问题地从每个表中清楚地选择所有记录。 我能够使用join语句来仅提取两个表中的记录
我想要完成的是一个查询,它将提取所有记录,但也加入报告表中的数据,同时仅显示报告中的LATEST加入记录(如果适用)。
工作联接查询的示例:
select * from table
join reports on (table.ID = reports.ID)
join contacts on (reports.cID = contacts.cID)
where date(reports.dTime) = date(curdate()) and reports.Method = $methodID
无效的修改查询示例。据我所知,我可能需要使用子查询,因为我的逻辑存在缺陷,并且OR不起作用我的想法
select * from table
join reports on (table.ID = reports.ID)
join contacts on (reports.cID = contacts.cID)
where date(reports.dTime) = date(curdate()) and reports.Method = $methodID OR table.Method = $method
我已尝试按照MySQL文档使用LEFT OUTER JOIN,但似乎无法将其包含在表中的所有记录以及报告中的任何可能数据。
select * from table
left outer join reports on (table.ID = reports.ID)
where date(reports.dTime) = date(curdate()) and reports.Method = $methodID
我做错了吗?或者我对加入缺乏的把握?
感谢您提供的任何帮助。
编辑 - 我刚刚意识到我不可能按报告时间或方法排序或排序,因为那些可能不存在,我不需要能够在此查询中排序。也许按table.timestamp命令。
编辑2 - 添加预期结果的示例:
table
-------------------------------------
firstName | last Name | cID | dTime
-------------------------------------
Jane | Doe | 312 | 10:30am
John | Doe | 318 | 10:35am
Adam | Doe | |
Berry | Doe | |
Charlie | Doe | |
表格表包含有关姓名,年龄等人的各种数据。联系人表格中只包含联系人ID(cid)以及联系人姓名和姓氏。报告表包含dTime和该dTime的cid,它对应于contacts表中的ContactID。联系人ID是唯一的。
答案 0 :(得分:1)
首先,您应始终提供您使用的真实代码。正如你所看到的(参见@Jay Blanchard的评论),如果你随意发布或更改名字,你会犯错误。
毕竟,你在这里发帖是因为你在某个地方有错误,错误将发生在你不期待它的地方。否则,你会自己找到它。
如果您认为由于某种原因无法披露您的真实代码,那么除了创建a minimal, complete and verifiable example之外别无他法。这是对所有试图帮助的人的态度和尊重。
您展示的代码不会运行,此外,您真的应该告诉我们$method
和$methodID
的来源以及计算方式。
其次,回到你的问题,我注意到一些非常不寻常的事情,哪些可能最终成为一个问题。我不确定,因为你没有显示你的表定义。
对于以下内容,为了明确我想说的内容,让我们假设您的表格table
实际上有persons
的名称,然后让我们看一下您的表persons
和reports
。
通常,在每个表中,您都有一个主键,通常称为ID
。当在两个表之间建立关系时,为了使数据库能够建立一个"连接"在两个表的行之间,您必须将另一个表中的一个表的ID
值存储在单独的列中。
在您的示例中,这意味着表格persons
有一列ID
而表reports
有一列ID
,但表reports
另外还有一个列PersonID
,其中存储了与该行相关的人的ID
。
但根据你的例子,你是这样加入的:
...
join reports on (persons.ID = reports.ID)
...
如果您使用常用方法并且每个表(包括ID
表)中的列reports
实际上只是行ID(主键),这没有意义。相反,你必须像这样加入:
...
join reports on (persons.ID = reports.PersonID)
...
第三(或者是母语人士会说"第三个"在这里?),如果你想只提取最后一条记录,你可以使用聚合函数分组。为此,请对SQL语句进行以下更改:
SELECT ...,
MAX(reports.dTime),
...
FROM ...
WHERE ...
GROUP BY persons.ID,
reports.cID
这将选择PersonID
和cID
的所有不同对,并显示每个此类对的上一次报告的日期/时间。
如果您希望按PersonID
(而不是PersonID
/ cID
对)显示上次报告的日期/时间,则可以从代码中删除最后一行以上。但是请注意,如果您仍然contacts
SELECT
表中的列,数据库将从contacts
表中的匹配行中选择 random 行
答案 1 :(得分:1)
如果我正确理解数据,下面的查询应该可以获得您正在寻找的结果:
SELECT t.firstName, t.lastName, c.id, r.dTime
FROM Table t
LEFT JOIN reports r ON r.id = t.id
LEFT JOIN contacts c ON c.id = r.cId
表和报告之间的关系似乎没有正确设置,除非您简化了实际结构。正如Binarus所指出的,您应该在Reports表中有一个tId列,以将Table id存储为外键。