繁体   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