Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 根据其他表中的条件在表中选择记录_Sql_Ruby On Rails 3_Postgresql_Join_Scope - Fatal编程技术网

Sql 根据其他表中的条件在表中选择记录

Sql 根据其他表中的条件在表中选择记录,sql,ruby-on-rails-3,postgresql,join,scope,Sql,Ruby On Rails 3,Postgresql,Join,Scope,在我正在使用的rails应用程序中,我有以下设置: class Volunteer < AR::Base has_many :engagements end class Engagement < AR::Base belongs_to :volunteer end 我正在将这些作用域与其他作用域合并以筛选志愿者 上述作用域:not_engaged_between生成以下SQL: SELECT "volunteers".* FROM "volunteers" INNER J

在我正在使用的rails应用程序中,我有以下设置:

class Volunteer < AR::Base
  has_many :engagements
end

class Engagement < AR::Base
  belongs_to :volunteer
end
我正在将这些作用域与其他作用域合并以筛选志愿者

上述作用域:not_engaged_between生成以下SQL:

SELECT "volunteers".* FROM "volunteers" INNER JOIN "accounts" ON "accounts"."user_id" = "volunteers"."id" AND "accounts"."user_type" = 'Volunteer' INNER JOIN "engagements" ON "engagements"."volunteer_id" = "volunteers"."id" WHERE (accounts.activation_state = 'active') AND (engagements.date NOT BETWEEN '2012-07-30' AND '2012-08-04')
问题是志愿者可能到目前为止没有任何约会,在这种情况下,查询完全忽略了这些志愿者。即使志愿者没有任何约会,我如何让他们返回

您需要一个不存在的文件来执行此操作。这种语法对SQL来说有点重,也许有更好的arel方法

scope :not_engaged_on, lambda { |q| where(["NOT EXISTS (SELECT ID from engagements WHERE engagements.date = ? AND volunteer_id = volunteers.id)", q])}

scope :not_engaged_between, lambda { |s, e| where(["NOT EXISTS (SELECT ID from engagements WHERE engagements.date BETWEEN ? AND ? AND volunteer_id = volunteers.id)", s, e]) }
您需要一个不存在的文件来执行此操作。这种语法对SQL来说有点重,也许有更好的arel方法

scope :not_engaged_on, lambda { |q| where(["NOT EXISTS (SELECT ID from engagements WHERE engagements.date = ? AND volunteer_id = volunteers.id)", q])}

scope :not_engaged_between, lambda { |s, e| where(["NOT EXISTS (SELECT ID from engagements WHERE engagements.date BETWEEN ? AND ? AND volunteer_id = volunteers.id)", s, e]) }

@Anthony已经提到了不存在。另一个选项是+检查是否存在e.U id为空:

在这种情况下,您必须将条件e.date在“2012-07-30”和“2012-08-04”之间移动到join子句中


如果帐户也可能丢失,请使用另一个左联接。但您似乎确实想检查用户类型和激活状态。

@Anthony已经提到的不存在。另一个选项是+检查是否存在e.U id为空:

在这种情况下,您必须将条件e.date在“2012-07-30”和“2012-08-04”之间移动到join子句中


如果帐户也可能丢失,请使用另一个左联接。但您似乎确实想检查用户类型和激活状态。

谢谢您的回答。但是,抛出NoMethodError:for的未定义方法'default\u scoped'。有什么想法吗?好的,我的答案。这可能不是最好的语法,但应该可以。谢谢你的帮助。不知何故,exists.not syntax和not exists对我不起作用。必须这样做才能使它工作:作用域:not|engaged|between,lambda{s,e|joinsLEFT JOIN engagements e ON e.志愿者id=志愿者.id和e.date不在{s}和{e}之间。其中[e.志愿者| id为NULL]},这将生成@Erwin建议的SQL。再次感谢你的帮助!由于我正在构建作用域并在运行查询之前合并它们,所以这种方法现在对我更有效,谢谢。谢谢你的回答。但是,抛出NoMethodError:for的未定义方法'default\u scoped'。有什么想法吗?好的,我的答案。这可能不是最好的语法,但应该可以。谢谢你的帮助。不知何故,exists.not syntax和not exists对我不起作用。必须这样做才能使它工作:作用域:not|engaged|between,lambda{s,e|joinsLEFT JOIN engagements e ON e.志愿者id=志愿者.id和e.date不在{s}和{e}之间。其中[e.志愿者| id为NULL]},这将生成@Erwin建议的SQL。再次感谢你的帮助!因为我正在构建范围并在运行查询之前将其合并,所以这种方法现在对我更有效,谢谢。谢谢。它是有效的,我必须这样定义它以生成所需的SQL:scope:not|engaged|between,lambda{s,e|joinsLEFT JOIN-engagements e ON e.志愿者id=志愿者.id和e.date不在{s}和{e}之间,其中[e.志愿者| id为NULL]}。再次感谢!!谢谢它是有效的,我必须这样定义它以生成所需的SQL:scope:not|engaged|between,lambda{s,e|joinsLEFT JOIN-engagements e ON e.志愿者id=志愿者.id和e.date不在{s}和{e}之间,其中[e.志愿者| id为NULL]}。再次感谢!!

SELECT v.*
FROM   volunteers       v
JOIN   accounts         a ON a.user_id = v.id
LEFT  JOIN engagements e ON e.volunteer_id = v.id
                        AND e.date BETWEEN '2012-07-30' AND '2012-08-04'
WHERE  a.user_type = 'Volunteer'
AND    a.activation_state = 'active'
AND   e.volunteer_id IS NULL;