问题描述
你好,
根据上面的sqlfiddle例子;
我有一个表 A,其中列出了产品,还有一个表 B,其中包含与这些产品相关的不同时期的不同价格。
但是,如果用户没有选择日期,我默认无法显示最接近今天的时段的价格。
在我给出的例子中,SQL查询成功地做到了这一点,但是我无法以laravel查询的形式成功地编写它。或者作为 Eloquent orm 查询
我该怎么做?
class Base:
def __init__(self):
self.a=3
self._a = 2 #protected member
class Derived(Base):
def __init__(self):
Base.__init__(self)
print("Calling protected member of base class: ")
print(self._a)
obj1 = Derived()
obj2 = Base()
print(obj2.a)
print(obj2._a)
note1:$postFrom 和 $postTo 是用户的开始和结束日期。如果用户没有提交日期,$postFrom 显示为 0。
注意2:当满足 $postFrom[0] == '0' 条件时,我会显示默认价格。
注意3:sqlfiddle示例中的'2021-03-07'值用于代替动态现值。
note4:根据此查询,默认取第一期的价格值。但这不是我想要的。
note5:我不能使用“joinSub”,因为 Laravel 版本是 5.5。
note6:在我想转换为 Laravel Query 形式的例子中,sql 查询没有任何问题:
$query->select(['tableA.*','tableB.start_date','tableB.end_date','tableB.price'])
->join('tableB',function($join) {
$join->on('tableA.id','=','tableB.pro_id');
})->where(function($sq) use ($postFrom) {
$sq->when($postFrom[0]=='0',function ($syq) {
$syq->whereRaw('DAYOFYEAR(curdate()) <= DAYOFYEAR(tableB.end_date)');
},function ($stq) use ($postFrom) {
$stq->whereDate('tableB.start_date','<=',$postFrom[0])
->whereDate('tableB.end_date','>=',$postFrom[0]);
});
})->orWhere(function($ssq) use ($postTo) {
$ssq->whereDate('tableB.start_date',$postTo[0])
->whereDate('tableB.end_date',$postTo[0]);
})->groupBy('tableA.id')->orderBy('tableB.price',$sortDirection);
解决方法
这是您查询的等效查询。我没有执行。
如果 Laravel 版本大于 5.5
$query1 = DB::table('tableB')
->selectRaw("id,start_date,end_date,pro_id,price,DATEDIFF(end_date,'2021-03-07') AS diff")
->groupBy('id')->orderBy('diff','ASC');
TableA::select('tableA.*','tableB.start_date','tableB.end_date','tableB.price')
->joinSub($query1,'tableB',function ($join)
{
$join->on('tableA.id','=','tableB.pro_id');
})
->whereDate('tableB.end_date','>=','2021-03-07')
->groupBy('tableA.id')->orderBy('price','DESC')->get();
对于 Laravel 5.5
TableA::select('tableA.*','tableB.price')
->join(DB::raw("(SELECT id,DATEDIFF(`tableB`.`end_date`,'2021-03-07') diff
FROM `tableB` GROUP BY id order by diff asc) table2 "),'table2.pro_id');
})
->whereDate('table2.end_date','DESC')->get();