我有以下SQL,可以通过特定的过滤器和排序为我提供数据库中特定记录的位置。
\DB::select("SELECT
t.id,
t.position
FROM (
SELECT estimations.id,
@rownum := @rownum + 1 AS position
FROM estimations
JOIN (SELECT @rownum := 0) r
WHERE estimations.is_archived = 1
ORDER BY estimations.start desc, estimations.name) t
WHERE t.id = " . $this->id);
对于内部查询,我想使用雄辩的模型Estimation
,以便可以使用其查询范围。我想使用该模型,以便如果将范围进行了下线更新,则此查询将反映出更改...
$innerQuery = Estimation::select('id')
->addSelect(\DB::raw('@rownum := @rownum + 1 AS position'))
// Need to add "JOIN (SELECT @rownum := 0) r"
->archived();
使用join
方法并传递一些通用参数...
$innerQuery = Estimation::select('id')
->addSelect(\DB::raw('@rownum := @rownum + 1 AS position'))
->join('(SELECT @rownum := 0) r', '1', '=', '1')
->archived();
虽然以上内容为我提供了正确的SQL(如果我将其转储),则$innerQuery->toSql()
在运行时会失败,$innerQuery->get()
并显示以下错误...
SQLSTATE [42S02]:未找到基表或视图:1146表'my_db。(选择@rownum:= 0)r'不存在(SQL:SELECT temp.id,temp.position FROM(选择`id `,@rownum:= @rownum + 1来自估计值内部联接的AS位置((SELECT @rownum:= 0)r`在`1` =`1`上,其中`is_archived` =?由`start` desc排序, `name` asc)temp WHERE temp.id = 4)
如上所述,但对DB::raw()
使用join()
(由Jonas Staudenmeir建议),
$innerQuery = Estimation::select('id')
->addSelect(\DB::raw('@rownum := @rownum + 1 AS position'))
->join(\DB::raw('(SELECT @rownum := 0) r'), '1', '=', '1')
->archived();
运行$innerQuery->get()
会导致以下错误...
SQLSTATE [42S22]:找不到列:1054“ on子句”中的未知列“ 1”(SQL:从“ estimations”内部联接中选择“ id”,@ rownum:= @rownum + 1个AS位置(SELECT @ rownum:= 0)r在`1` =`1`上,其中`is_archived` = 1顺序由`start` desc,`name` asc)
如上所述,为所有DB::raw()
值添加join()
(再次感谢Jonas Staudenmeir),
$innerQuery = Estimation::select('id')
->addSelect(\DB::raw('@rownum := @rownum + 1 AS position'))
->join(\DB::raw('(SELECT @rownum := 0) r'), \DB::raw('1'), '=', \DB::raw('1'))
->archived();
这可以单独使用$innerQuery->get();
,但是当插入外部查询时
$res = \DB::select('SELECT
t.id,
t.position
FROM (' . $innerQuery->toSql() . ') t
WHERE t.id = ' . $this->id);
我收到错误消息...
SQLSTATE [HY000]:一般错误:2031(SQL:SELECT t.id,t.position FROM(选择“ id”,@ rownum:= @rownum + 1个来自“ estimations”内部联接的AS位置(SELECT @rownum := 0)r = 1 = 1,其中“ is_archived” =?由“ start” desc,“ name” asc排序)t WHERE t.id = 3)
这是因为scopeArchived()
按一个值过滤,该值在错误中显示为?
吗?如何避免这种情况?
这是scopeArchived()
的代码
public function scopeArchived($query)
{
return $query->where('is_archived', true)->ordered('start', 'desc');
}
删除->where('is_archived', true)
不会导致任何错误,但显然不会导致我追求的结果。
(感谢Jonas Staudenmeir)-对外部查询使用fromSub()
。这是完整的代码...
$innerQuery = Estimation::select('id')
->addSelect(\DB::raw('@rownum := @rownum + 1 AS position'))
->join(\DB::raw('(SELECT @rownum := 0) r'), \DB::raw('1'), '=', \DB::raw('1'))
->archived();
$res = \DB::query()->fromSub($innerQuery, 'temp')
->select('id', 'position')
->where('id', $this->id)
->first();
答案 0 :(得分:1)
JOIN的“表”和“列”不能放在反引号中。您必须使用原始表达式:
->join(DB::raw('(SELECT @rownum := 0) r'), DB::raw('1'), '=', DB::raw('1'))