【发布时间】:2014-07-25 22:17:50
【问题描述】:
我相当擅长 PHP(OOP 和平面)。在过去一年左右的时间里,我一直负责维护 Ruby 代码库。一项我仍在学习的技能。我不太清楚如何使用 Sequel 正确构建过滤链,以便可以正确包含 AND 以及 OR 语句。
这是我想要的 MySQL 查询结构:
SELECT * FROM `some_objects`
WHERE (
(
((`datebegin` >= 1950) AND (`datebegin` <= 1959)) OR ((`dateend` >= 1950) AND (`dateend` <= 1959))
)
OR
((`datebegin` <= 1950) AND (`dateend` >= 1959))
AND
(NOT `datebegin` = 0) AND (NOT `dateend` = 0)
)
;
这是我正在使用的 Sequel 代码片段:
some_objects = where{((datebegin >= start_year) & (datebegin <= end_year)) | ((dateend >= start_year) & (dateend <= end_year))}.
or{(datebegin <= start_year) & (dateend >= end_year)}.
where(~:datebegin => 0, ~:dateend => 0)
这就是我实际得到的:
SELECT * FROM `some_objects`
WHERE (
(
((`datebegin` >= 1950) AND (`datebegin` <= 1959)) OR ((`dateend` >= 1950) AND (`dateend` <= 1959))
OR
((`datebegin` <= 1950) AND (`dateend` >= 1959))
)
AND
(NOT `datebegin` = 0) AND (NOT `dateend` = 0)
)
;
我还尝试了相同 Sequel 代码的不同变体,例如:
some_objects = where(:datebegin => start_year..end_year).
or(:dateend => start_year..end_year).
or{|o|(o.datebegin <= start_year) & (o.dateend >= end_year)}.
where(~:datebegin => 0, ~:dateend => 0)
还有这个:
some_objects = where(:datebegin => start_year..end_year).
or(:dateend => start_year..end_year).
or{(datebegin <= start_year) & (dateend >= end_year)}.
where(~:datebegin => 0, ~:dateend => 0)
但我仍然得到第一个 SQL 结构,其中整个块基本上是 ((AND OR AND OR)):
(
((`datebegin` >= 1950) AND (`datebegin` <= 1959)) OR ((`dateend` >= 1950) AND (`dateend` <= 1959))
OR
((`datebegin` <= 1950) AND (`dateend` >= 1959))
)
当我想要((AND OR AND) OR)时:
(
((`datebegin` >= 1950) AND (`datebegin` <= 1959)) OR ((`dateend` >= 1950) AND (`dateend` <= 1959))
)
OR
((`datebegin` <= 1950) AND (`dateend` >= 1959))
【问题讨论】:
-
使用
BETWEEN操作符会更容易吗?这减少了AND案例的数量。 -
@tadman 我同意。但我不是这样设置的。但是您正在查看 Sequel 在 Ruby 中生成的 SQL;我输出 MySQL 输出来得到它。我正在处理的是 Ruby Sequel GEM 处理 SQL 生成的方式。所以如果有办法让
BETWEEN工作,当然可以。美好的。但这暂时是多余的。