[英]Laravel DB Query WHERE date greater than not working with JOIN
我已經編寫了一個 SQL 查詢,它非常適合我的需求,我正在嘗試將它添加到 Laravel 中的排隊作業中。 我不想使用 Eloquent 模型,而是想使用帶有 DB Query 的 go 來確保更好的性能,因為最終會有很多連接和條件。 我在檢查日期時遇到了where
子句的問題,但是在 SQL 中運行時它工作得非常好。 我已經刪除了此查詢的其他部分,僅包含調試此問題所需的內容。
原廠SQL:
SELECT `messages`.`created_at`, `participants`.`last_read`
FROM `messages`
LEFT JOIN `participants` ON `messages`.`thread_id` = `participants`.`thread_id` AND `messages`.`user_id` != `participants`.`user_id`
WHERE `messages`.`created_at` > `participants`.`last_read`;
當我直接在 SQL 中運行它時,我看到 2 個結果,這是我當前數據所預期的。
created_at | 上次閱讀 |
---|---|
2021-03-26 19:02:53 | 2021-03-23 19:31:30 |
2021-03-26 19:02:58 | 2021-03-23 19:31:30 |
這就是我在 Laravel 中的寫法:
$query = DB::table('messages')
->leftJoin('participants', function ($join) {
$join->on('messages.thread_id', '=', 'participants.thread_id')
->on('messages.user_id', '!=', 'participants.user_id');
})
->select('messages.created_at as message_date', 'participants.last_read as last_read')
->where('messages.created_at', '>', 'participants.last_read');
當我執行此操作時,結果為空。 我從 DB Query builder 中轉儲了最終的 SQL 以確保它是正確的,這就是它:
select `messages`.`created_at` as `message_date`, `participants`.`last_read` as `last_read`
from `messages`
left join `participants`
on `messages`.`thread_id` = `participants`.`thread_id` and `messages`.`user_id` != `participants`.`user_id`
where `messages`.`created_at` > participants.last_read
正如預期的那樣,直接在 SQL 中運行它會返回准確的結果。
對於上下文,這是我正在使用的數據結構和一些數據。
參與者
ID | 線程 ID | 用戶身份 | 上次閱讀 | created_at | 更新時間 | 刪除_at | 最后通知 |
---|---|---|---|---|---|---|---|
9 | 8 | 178 | 2021-03-23 23:31:53 | 2021-03-23 22:16:48 | 2021-03-23 23:31:53 | NULL | NULL |
消息
ID | 線程 ID | 用戶身份 | 身體 | created_at | 更新時間 | 刪除_at |
---|---|---|---|---|---|---|
159 | 3 | 177 | 阿法德 | 2021-03-26 19:02:53 | 2021-03-26 19:02:53 | NULL |
160 | 3 | 177 | 爸爸 | 2021-03-26 19:02:58 | 2021-03-26 19:02:58 | NULL |
似乎數據庫查詢代碼導致名稱相似的列混淆。 兩個表都有一個名為created_at
的列,但我只需要messages
表中的該列。 我的SELECT
只要求該列,指定正確的表。 但是這個數據庫查詢連接中的某些東西導致它混淆了。
使用不同的連接並刪除where
子句,我意識到日期並不總是正確的。 例如,這是我使用leftJoin
時的結果
{
"message_date": "2021-03-23 00:30:42",
"last_read": "2021-03-26 00:22:48"
},
{
"message_date": "2021-03-23 00:31:25",
"last_read": "2021-03-26 00:22:48"
}
請注意, message_date
和last_read
值與直接運行 SQL 時的值相反。 所以這一定是問題所在。
我改成rightJoin
,結果反過來了:
{
"message_date": "2021-03-26 19:02:53",
"last_read": "2021-03-23 19:31:30",
},
{
"message_date": "2021-03-26 19:02:58",
"last_read": "2021-03-23 19:31:30",
}
所以這應該有效,對吧? 我重新添加了where
子句,但結果仍然是空的。
我猜我需要做一些事情來告訴查詢生成器正確處理這些列,因為它們似乎在where
和select
期間混淆了。 但我不知道如何澄清這一點。 我曾嘗試尋找其他有此問題的人,但似乎找不到任何相關內容。
我已經嘗試了一些結果沒有改變的東西。
select()
移到語句的開頭,就像這樣。whereDate
而不是where
。 (注意 - 為了性能,我寧願避免這種情況,但想以防萬一)。join
、 joinLeft
和joinRight
。on
子句中使用where
而不是兩個on
s。 像這樣->leftJoin('participants', function ($join) { $join->on('messages.thread_id', '=', 'participants.thread_id') ->where('messages.user_id', ',='. 'participants;user_id'); })
有人對我可以嘗試的事情有任何指導嗎? 這應該是一個如此簡單的任務,並且已經變成了試圖理解為什么它在 SQL 而不是 Laravel 的 DB Query Builder 中工作的幾個小時。
查詢生成器的where
function 將始終假定右側是一個值,並將在准備好的語句中將其用作文字(在本例中為字符串)。 如果要比較列,則需要使用whereColumn
:
$query = DB::table('messages')
->leftJoin('participants', function ($join) {
$join->on('messages.thread_id', '=', 'participants.thread_id')
->on('messages.user_id', '!=', 'participants.user_id');
})
->select('messages.created_at as message_date', 'participants.last_read as last_read')
->whereColumn('messages.created_at', '>', 'participants.last_read')->get();
可以在 文檔中找到其他 where 子句
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.