簡體   English   中英

MySQL的拉所有記錄與聯接問題

[英]MySQL Pull All records with join issue

我有一個奇怪的情況。 我還沒有找到解決方案,我嘗試使用各種聯接和子查詢,因此我需要一些幫助。 我正在使用MySQLi和PHP 7。

我有兩張桌子。 一個表(稱為表)包含一個人員列表。 另一個表包含該人已完成的數據日志,稱為報告。

我可以毫無問題地從每個表中選擇所有記錄。 我能夠使用join語句僅提取兩個表中的記錄

我想要完成的是一個查詢,該查詢將提取所有記錄,但還會從報告表中聯接數據,同時僅顯示報告中的最新聯接記錄(如果適用)。

工作聯接查詢的示例:

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 

修改后的查詢不起作用的示例。 我了解我可能需要使用子查詢,因為我的邏輯存在缺陷,或者我認為它無法正常工作

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

我做錯什么了嗎? 還是缺乏對Joins的掌握?

感謝您提供的任何幫助。


編輯-我只是意識到我無法按照報告時間或方法進行排序或排序,因為這些時間或方法可能不存在,因此我不需要在此查詢中進行排序的功能。 也許通過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       |  | 

表Table包含有關人員的各種數據,例如姓名,年齡等。聯系人表僅包含聯系人ID(cid)以及聯系人的名字和姓氏。 報告表包含dTime和該dTime的cid,該cid對應於聯系人表中的ContactID。 聯系人ID是唯一的。

首先 ,您應該始終提供您使用的真實代碼。 如您所見(請參閱@Jay Blanchard的評論),如果您隨意散布或更改名稱,將會出錯。

畢竟,您之所以在這里發布是因為某個地方有錯誤,並且該錯誤將發生在您不希望出現的地方。 否則,您將自己找到它。

如果您覺得由於某種原因無法公開您的真實代碼,那么除了創建一個最小,完整和可驗證的示例之外,別無其他方法。 這是對所有試圖幫助的人的態度和尊重的問題。

您顯示的代碼將無法運行,此外,您確實應該告訴我們$method$methodID來源以及如何計算它們。

其次,回到您的問題上,我注意到了一些非常不尋常的事情, 最終可能會成為問題。 我不確定,因為您沒有顯示表定義。

在下面,為了明確我的意思,讓我們假設您的table實際上具有名稱persons ,然后讓我們看一下您的表personsreports

通常,在每個表中,您都有一個主鍵,通常稱為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

這將選擇所有不同的PersonIDcID對,並顯示每個此類的上一次報告的日期/時間。

如果要顯示每個PersonID (而不是每個PersonID / cID對)的最后報告的日期/時間,則可以cID上面代碼中的最后一行。 但是請注意,如果您仍然從contacts表中SELECT一列,那么數據庫將從contacts表中的匹配行中選擇一個隨機行。

如果我正確理解了數據,則以下查詢應為您提供所需的結果:

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存儲為外鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM