簡體   English   中英

如果包括且僅當查詢不適用於Rails和Postgres時,才使用join進行所有操作

[英]All off with join if includes if and only if query does not work with Rails and Postgres

我想要的是查詢僅具有通過habtm關聯關聯的“ fra”語言的所有媒體。 當前,該查詢返回的Media實例包括“ fra”,例如[“ fra”,“ eng”]。 我使用Postgres。

因此,(1)我想找到完全具有語言“ x”的媒體,而沒有其他媒體;(2)找到完全具有語言“ x”和“ y”的媒體,(3)找到具有完全語言的媒體。恰好是語言“ x”,“ y”和“ z”等。

class Media < ActiveRecord::Base
    has_and_belongs_to_many :audio_language_records, :join_table => "audio_languages_media", :class_name => "Language"
end

class Language < ActiveRecord::Base
  attr_accessor :code
end

我已經嘗試過了,但是它返回的所有媒體都包括“ fra”,而不僅僅是“ fra”

Media.joins(:audio_language_records).where("languages.code = ? AND languages.code != ?", "fra", "eng")

以下內容無法按預期運行,並返回相同結果

Media.joins(:audio_language_records).where("languages.code IN (?) AND languages.code NOT IN (?)", ["fra"], ["eng"])

因此,您需要找到存在一個language.code為“ eng”的Media,但聯接表中沒有針對相同media_id但不同language_id的條目。

SELECT * FROM media m1
  JOIN audio_languages_media alm1 ON alm1.media_id = m1.id
  JOIN languages l1 ON alm1.language_id = l1.id 
  WHERE NOT EXISTS(
    SELECT 1 FROM audio_languages_media alm2
    WHERE alm1.language_id != alm2.language_id
    AND alm1.media_id = alm2.media_id
  )
  AND l1.code = 'eng';

讓我們知道這是否是正確的數據庫查詢,以便我們為AREL提供幫助。

編輯:查詢何時要查找至少在“ eng”和“ fra”中的媒體

SELECT * FROM media m1
  WHERE(
    SELECT count(*) FROM audio_languages_media alm2
    JOIN languages l2 ON alm2.language_id = l2.id
    WHERE l2.code in ('eng','fra')
    AND alm2.media_id = m1.id
  ) > 1;

編輯:添加@chinshr的查詢

如果您想要僅具有“ eng”和“ fra”的媒體

SELECT * FROM media m1
  WHERE(
    SELECT count(*) FROM audio_languages_media alm2
    JOIN languages l2 ON alm2.language_id = l2.id
    WHERE l2.code IN ('eng','fra')
    AND alm2.media_id = m1.id
    AND (
      SELECT count(*) FROM audio_languages_media alm2 
      WHERE alm2.media_id = media.id
    ) = 2
  ) = 2;

可以通過在IN數組中添加/刪除該查詢來調整或多或少的語言,並將末尾的計數調整為等於IN數組中的元素數。

為了使它可靠地工作,您必須在audio_languages_media(media_id,language_id)上具有唯一索引;

每行只有一個值,因此每個“ fra”值不能為“ eng”或任何其他值。 您將不得不檢查兩行。 例如,可以在SQL中完成此操作:

SELECT * 
FROM languages t1
LEFT JOIN languages t2
    ON t1.id=t2.id AND t2.code="eng"
WHERE t1.code="fra" AND t2.code IS NULL;

暫無
暫無

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

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