Postgresql DBIx::Class/SQL::Abstract将SQL函数应用于WHERE子句中的列
我只是摆弄了一下用生成的复杂SQL查询(它在后台用于WHERE子句) 我正在使用BETWEEN运算符筛选条目:Postgresql DBIx::Class/SQL::Abstract将SQL函数应用于WHERE子句中的列,postgresql,perl,dbix-class,Postgresql,Perl,Dbix Class,我只是摆弄了一下用生成的复杂SQL查询(它在后台用于WHERE子句) 我正在使用BETWEEN运算符筛选条目: # SELECT title FROM tracks WHERE begin BETWEEN '2016-07-01' AND '2016-07-02' $searchArgs->{'begin'} = { BETWEEN => ['2016-07-01', '2016-07-02' ] }; 这将跳过2016-07-02的实际开始日期。可能是因为这些开始值超过了2016
# SELECT title FROM tracks WHERE begin BETWEEN '2016-07-01' AND '2016-07-02'
$searchArgs->{'begin'} = { BETWEEN => ['2016-07-01', '2016-07-02' ] };
这将跳过2016-07-02的实际开始日期。可能是因为这些开始值超过了2016-07-02的午夜(00:00),因此不在中间范围内(参见末尾的示例数据)
在SQL方面,这很容易解决:
SELECT title FROM tracks WHERE DATE(begin) BETWEEN '2016-07-01' AND '2016-07-02'
# Note the DATE()-cast of begin
有没有一种方法可以通过SQL::Abstract
语法实现这一点?我尝试将列名作为标量引用($searchArgs->{\“DATE(begin)”}
)来传递它,但没有成功
仅仅使用$searchArgs->{'DATE(begin)}
会触发一个SQL错误,因为没有这样的列“DATE(begin)”
问题似乎是像“2016-07-02”这样的日期相当于“2016-07-02T00:00:00”,“2016-07-02T12:00:00”大于此日期。调用
DATE()
我建议您放弃介于
之间的,使用等效的=
和='2016-07-01'并开始2016-07-03';
或者,在DBIx::Class
$searchArgs->{begin}={
'>=' => '2016-07-01',
'=' => '2016-07-01',
“什么是”但它不起作用“是什么意思?我找不到方法,在列端获取DATE()-函数。当然,但尝试时发生了什么?我收到一个SQL引擎错误,该错误抱怨不存在列名“SCALAR…”。因为哈希中的SCALAR Ref as键不是以特殊方式计算的,就像值一样(标量引用通常以简单的SQL语句结束)。好的,那么你应该将这些信息添加到你的问题中。我下面的答案对你来说是否不足?你的解决方案意味着一些日期数学(2016-07-31+1天=>2016-08-01)。realy查询稍后会动态执行。除此之外,它还可以工作(但不包括BETWEEN)。但这可能不再是DBIx::Class/SQL::Abstract问题了。鉴于上述限制,我必须进一步研究它的外观…@ghandi:好吧,那么就用一些显式SQL来做算术。“不用担心,只是不再在线。;日期(…)+1
是一个很好的解决方法。谢谢:)
# Minimal example data
CREATE TABLE test ( title VARCHAR(255), begin timestamp );
INSERT INTO test (title, begin) VALUES ( 'Track 1', '2016-07-01T12:00:00'::timestamp), ( 'Track 2', '2016-07-02 12:00:00'::timestamp );
SELECT title FROM test WHERE begin BETWEEN '2016-07-01' AND '2016-07-02';
SELECT title FROM test WHERE DATE(begin) BETWEEN '2016-07-01' AND '2016-07-02';
$searchArgs->{begin} = {
'>=' => '2016-07-01',
'<' => \[ 'date(?) + 1', '2016-07-02' ],
};