簡體   English   中英

使用double innerJoin()的奇怪主義行為

[英]Strange Doctrine behaviour with double innerJoin()

我有這樣的數據庫模式:我的數據庫模式: http//i.stack.imgur.com/vFKRk.png

解釋上下文:一個用戶寫一條消息。 他可以將其發送給一個或多個用戶。

我成功地獲得了一個用戶的作者的消息標題。 然而,我用於此項目的Doctrine使用2個查詢來完成它。 這對我來說有點奇怪,我希望了解,為什么。 通常,我們可以使用一個SQL查詢來完成。

我的DQL查詢:

$q = Doctrine_Query::create()->select('id_me, users_id_us, state_me, type_me, mc.title_mc, us.login_us') ->from('messages m')->innerJoin('m.messages_content mc')->innerJoin('mc.Users us') ->where('users_id_us = ?', $user)->limit($opt['limit'])->offset($opt['offset'])->orderBy($opt['order']);return $q->fetchArray();

Doctrine返回的SQL查詢:

SELECT DISTINCT m3.id_me FROM messages m3  INNER JOIN messages_content m4 ON m3.messages_content_id_mc = m4.id_mc  INNER JOIN users u2 ON m4.users_id_us = u2.id_us WHERE m3.users_id_us = '6' ORDER BY m3.id_me DESC LIMIT 2

SELECT m.id_me AS m__id_me, m.users_id_us AS m__users_id_us, m.state_me AS m__state_me, m.type_me AS m__type_me, m2.id_mc AS m2__id_mc, m2.title_mc AS m2__title_mc, u.id_us AS u__id_us, u.login_us AS u__login_us FROM messages m INNER JOIN messages_content m2 ON m.messages_content_id_mc = m2.id_mc INNER JOIN users u ON m2.users_id_us = u.id_us WHERE m.id_me IN ('11') AND (m.users_id_us = '6') ORDER BY m.id_me DESC

為什么我的Doctrine查詢不會像這樣返回查詢:

SELECT m.id_me, m.users_id_us, m.state_me, m.type_me, mc.title_mc, u.login_us FROM messages m JOIN messages_content mc ON mc.id_mc = m.messages_content_id_mc JOIN users u ON u.id_us = mc.users_id_us WHERE m.users_id_us = 6;

有沒有想過轉換我的DQL查詢並執行一次?

ORM限制問題

這與LIMIT部分有關。 :) Doctrine LIMIT與MySQL限制有點不同。

MySQL LIMIT只發出查詢,並在找到與您的SQL查詢匹配的n行后立即停止搜索。 由於在ORM中,這確實是意外行為(很可能是在標量布局中,SQL SELECT * FROM myModel LEFT JOIN someOtherModel ON someCondition LIMIT 3實際上僅返回一個myModel實例,而不是三個,因為SELECT * FROM myModel LEFT JOIN someOtherModel ON someCondition LIMIT 3可以導致3行。

教義是做什么的?

如果您的DQL查詢是FROM school s INNER JOIN s.students LIMIT 15 ,它意味着:給我的15個實例school有至少一個student相關的(因此INNER JOIN ),及其所有的student同伙。 要做到這一點,Doctrine首先要求DISTINCT school使用完全相同的查詢參數和LIMIT部分,以確定應該返回哪15個學校ID。 完成此操作后,接下來將查詢這些ID,而不使用LIMIT部分。

如何解決您的問題

如果你沒有實際的問題,huzzah,找到上述這種行為的解釋。 如果您的查詢輸出不是您預期的,請確保將這些步驟納入考慮范圍。 例如,如果您的DQL是FROM school s INNER JOIN s.students LIMIT 15 ,並且您想知道為什么您有超過15名學生,請嘗試: FROM students s INNER JOIN s.school LIMIT 15 在MySQL中,這意味着基本相同(忽略結果的順序),但在Doctrine中,這意味着您將獲得15 students而不是15 schools

這對於一些更復雜的查詢也很困擾。 我發現的唯一解決方案是完全繞過愚蠢:

$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$my_result = $q->fetchAssoc(" ... PUT SQL HERE ... ");

有效的解決方案:

我更改了關系別名,並指定了messages_content和users之間參與ON聯合的列。

正確的Doctrine查詢是:

$q = Doctrine_Query::create()
->select('id_me, users_id_us, state_me, type_me, mc.title_mc, us.login_us') 
->from('messages m')
->innerJoin('m.messages_content mc')
->innerJoin('m.Users us ON mc.users_id_us=us.id_us')    
->where('users_id_us = ?', $user)
->limit($opt['limit'])
->offset($opt['offset'])
->orderBy($opt['order']);

它提供了這樣的SQL查詢:

SELECT m.id_me AS m__id_me, m.users_id_us AS m__users_id_us, m.state_me AS m__state_me, m.type_me AS m__type_me, m2.id_mc AS m2__id_mc, m2.title_mc AS m2__title_mc, u.id_us AS u__id_us, u.login_us AS u__login_us FROM messages m INNER JOIN messages_content m2 ON m.messages_content_id_mc = m2.id_mc INNER JOIN users u ON (m2.users_id_us = u.id_us) WHERE (m.users_id_us = '7') ORDER BY m.id_me DESC LIMIT 2

Tom和Pelle ten Cate,感謝您的參與。

暫無
暫無

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

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