laravel 分别选择最大和最小通过条件

bwleehnv  于 2023-02-17  发布在  其他
关注(0)|答案(3)|浏览(192)

当一个帖子被访问时,除了返回这个帖子的信息之外,我还需要返回前一个帖子(如果它存在)和下一个帖子。
我想知道是否有一种方法可以在单个查询/选择中选择MAX(id)MIN(id),并为它们中的每一个传递一个条件。这是我尝试在Laravel中执行的操作的示例,我将用SQL编写它以使其更简单
拉腊维尔:

$query = Post::query();
$query = $query->from('posts')->select(DB::raw('MAX(id), MIN(id)'))->whereRaw("id < {$id} and id > {$id}")->first();

SQL语句:

select MAX(id), MIN(id) from `posts` where id < 5 and id > 5 limit 1

id变量是post id值,在本例中,它的值为5。我所做的查询是获取引用此id的MAX和MIN,但我还需要获取用户访问的post的信息。
数据库中有4号和6号帖子,也就是说,在本例中,我需要从4号、5号和6号帖子中获取信息。
where条件永远不会是true,但我不能使用or,第一个条件是MAX,第二个条件是MIN,如果我使用or,最大的id将来自DB。
我需要将最小值和最大值与某个值进行比较。也就是说,正如我上面解释的那样。如果id是5,我需要获取该值以下的最大现有id(),还需要获取该值以上的最小值。在我的示例中,根据DB中的信息,它将是id 4、5和6
有可能在一次咨询中进行吗?还是我真的必须进行不止一次?

mqkwyuun

mqkwyuun1#

可以,您可以使用case-when执行此操作

select MAX(
           CASE
               WHEN id < 5 THEN id
               ELSE NULL
           END
       ), MIN(
           CASE
               WHEN id > 5 THEN id
               ELSE NULL
           END
       )
from `posts` 
where id <> 5

编辑

相当于Laravel,Gabriel Edu在评注部分分享

$query = Post::query();
$query = $query->from('posts')->
         select(DB::raw("MAX(CASE WHEN id < {$id} THEN id ELSE null END), MIN(CASE WHEN id > {$id} THEN id ELSE null END)"))->first();
1tu0hz3e

1tu0hz3e2#

MySQL中的LEAD()和LAG()函数用于获取其分区中任意行的前后值。
试试这个:

SELECT ID,
         LAG (id) OVER (ORDER BY NULL) ONE_SHIFT_FORWARD,
         LEAD (id) OVER (ORDER BY NULL) ONE_SHIFT_BACKWARD
    FROM POSTS
ORDER BY ID ASC;

SELECT *
  FROM (  SELECT ID,
                 LAG (id) OVER (ORDER BY NULL) ONE_SHIFT_FORWARD,
                 LEAD (id) OVER (ORDER BY NULL) ONE_SHIFT_BACKWARD
            FROM POSTS
        ORDER BY ID ASC)
 WHERE id = 5;

3xiyfsfu

3xiyfsfu3#

您可以使用leadlag来访问当前行之前和之后的值,然后可以使用这些值来选择具有给定ID的帖子以及在单个选择中的之前和之后的值。
以下查询

select * 
    from (
    select 
        p.*,
        lead(id) over(order by id) _lead,
        lag(id) over(order by id) _lag
    from post p
) x
where 23 in (id, _lead, _lag);

导致
| 身份证|正文|- -铅|- -滞后|
| - ------|- ------|- ------|- ------|
| 十五|十五|二十三|十个|
| 二十三|二十三|二十四|十五|
| 二十四|二十四|五十|二十三|
使用以下设置:

    • 架构(MySQL v8.0)**
create table post (
    id integer,
    text varchar(50)
);
    
insert into post(id, text)
values
( 10, 'ten'),
( 15, 'fifteen'),
( 23, 'twentythree'),
( 24, 'twentyfour'),
( 50, 'fifty');

View on DB Fiddle

相关问题