在我有以下型號的應用程序:瞭解查詢(包括聯接,條件)
class Activity < ActiveRecord::Base
has_many :activity_items, dependent: :destroy
has_many :children, through: :activity_items, source: :activity_itemable, source_type: 'Child'
has_many :parents, through: :activity_items, source: :activity_itemable, source_type: 'Parent'
...
end
ActivityItem用於參與者添加到活動
class ActivityItem < ActiveRecord::Base
belongs_to :activity_itemable, polymorphic: true
belongs_to :activity
has_many :children, through: :activity_itemable, source_type: 'Child'
has_many :parents, through: :activity_itemable, source_type: 'Parent'
...
end
的活動有一個日期列:'activity_date',以及其他在此不重要的列。
ActityItem具有state,activity_id,activity_itemable_type和activity_itemable_id列。
我已經建立計數參與者「統計」報告(許多家長是如何在活動列表中,許多不同的家長如何存在等)
我已經建立查詢來算,但我有麻煩了解生成的SQL我需要幫助在這裏確定我正在做好查詢。
下面是我的一些疑問,我的問題:
1 - 我想我算多少不同的孩子(有型兒童activity_items)在活動,但只有在比2015年12月31日較舊的活動
Activity.where("activity_date > ?", "2015-12-31").includes(:activity_items).where("activity_items.activity_itemable_type = ?", "Child").references(:activity_items).distinct.count("activity_items.activity_itemable_id")
SQL:
SELECT DISTINCT COUNT(DISTINCT activity_items.activity_itemable_id)
FROM "activities" LEFT OUTER JOIN
"activity_items"
ON "activity_items"."activity_id" = "activities"."id"
WHERE (activity_date > '2015-12-31') AND (activity_items.activity_itemable_type = 'Child')
因爲有上兩個不同的表的兩個條件,是不是更適合於使用一個內連接只選擇行毫安考慮這兩個條件?
2 - 相同的查詢,但我從另一個表
ActivityItem.includes(:activity).where('activity_date >= ?', "2015-01-01").where(activity_itemable_type: "Child").distinct.count(:activity_itemable_id)
同樣的結果開始,但很少有奇怪的事情。 I'dont必須寫在where子句像查詢1.我第一次嘗試寫:
.where('activity.activity_date >= ?', "2015-01-01")
但是它沒有我必須使用:
.where('activity_date >= ?', "2015-01-01")
最後這有什麼奇怪的是左外連接。左邊的表是activity_items,所以不是它應該加載此表中的所有行?這就像我使用的所有查詢返回相同的結果,就像它像INNER JOIN一樣行事。
SELECT DISTINCT COUNT(DISTINCT "activity_items"."activity_itemable_id")
FROM "activity_items" LEFT OUTER JOIN
"activities" ON "activities"."id" = "activity_items"."activity_id"
WHERE (activity_date >= '2015-01-01') AND "activity_items"."activity_itemable_type" = 'Child'
如果我使用連接而不是包括我得到了相同的結果,但與INNER JOIN。另一個奇怪的事情是:如果我沒有指定不同但只是計數(with_attribute_i_want_to_count),SQL仍然包含不同的。但是查詢的導軌指南指出,只有在給定的屬性填充到數據庫中時它才應該計數。
我測試我的查詢和結果是好的,但我不知道如何解釋和理解生成的SQL。
您如何理解這個欄中的LEFT OUTER JOIN例子?
當我用兩個表中的「includes」和條件啓動一個查詢時,我應該期待什麼?
你有一些文件來推薦澄清我的情況嗎?
感謝您閱讀這個奇怪的問題!
嗨戈登感謝您的回答。這有助於我澄清我的想法。其實我使用標準的軌道「發電機」的查詢,因爲它對我來說真的很快。但是當我構建更復雜的查詢時,我決定挖掘SQL,就好像我想通過好奇心來檢查生成器的輸出。我認爲是時候對普通的SQL查詢進行深入瞭解了。你有任何閱讀推薦或教程,可以幫助我嗎?如果直接與軌道沒有關係,這不是問題。 –
只是另一個小問題,當你說左外連接變爲內連接。它總是如此嗎?我的意思是如果一個左邊的外部條件在兩個表上都會是內部連接?謝謝 –
如果where子句在「left join」的第二個表上有條件,並且條件過濾掉了NULL值,那麼where子句將產生與「inner join」相同的結果集。他們可能沒有相同的執行計劃,但結果是一樣的。 –