php - MySQL中有没有办法根据CASE动态定义运算符?

标签 php mysql join left-join

我有一个查询,它连接自身以获取每个唯一列表的最新或最旧的订单记录。

SELECT
    lists.ordered,
    cnt1.*
FROM 
    cnt_lists as cnt1
    LEFT JOIN 
        lists
        on 
            cnt1.list_id = lists.id
    LEFT JOIN 
        cnt_lists as cnt2
        on 
            (cnt1.list_id = cnt2.list_id AND cnt1.id < cnt2.id)

WHERE
    cnt2.id is null and cnt1.list_id in ('3176', '3295', '3296') and cnt1.listable_type = 'Movie';

这个查询效果很好,但是lists.ordered可以是 0 或 1。当 lists.ordered = 0 时我想要 on 中的运算符声明为cnt1.id < cnt2.id但是当 lists.ordered = 1我希望将其逆转cnt1.id > cnt2.id .

有没有办法根据 CASE 动态定义运算符陈述?下面的内容不起作用,但我正在考虑想法。

SELECT
    lists.ordered,
    CASE
        WHEN lists.ordered = 1 THEN '>'
        ELSE '<'
    END AS operator,
    cnt1.*
FROM 
    cnt_lists as cnt1
    LEFT JOIN 
        lists
        on 
            cnt1.list_id = lists.id
    LEFT JOIN 
        cnt_lists as cnt2
        on 
            (cnt1.list_id = cnt2.list_id AND cnt1.id operator cnt2.id)

WHERE
    cnt2.id is null and cnt1.list_id in ('3176', '3295', '3296') and cnt1.listable_type = 'App\\Models\\Movie';

是否有一种方法可以提取每个列表的最高顺序和最低顺序,并且我可以确定在 PHP 端使用这两条记录中的哪一条?

我只是在寻找想法,因为我试图避免必须单独查询每个列表的 N + 1 查询问题。

最佳答案

依赖动态查询是很困惑的。您最好将该运算符拉入 WHERE查询的一部分并将其与 OR 配对:

SELECT
    lists.ordered,
    cnt1.*
FROM 
    cnt_lists as cnt1
    LEFT JOIN 
        lists
        on 
            cnt1.list_id = lists.id
    LEFT JOIN 
        cnt_lists as cnt2
        on 
            (cnt1.list_id = cnt2.list_id)

WHERE
    cnt2.id is null and cnt1.list_id in ('3176', '3295', '3296') 
    and cnt1.listable_type = 'Movie'
    AND (
       cnt2.id IS NULL /* Including this here because you have a LEFT JOIN */
       (lists.ordered = 1 AND cnt1.id < cnt2.id) OR 
       (lists.ordered = 0 AND cnt1.id > cnt2.id)
    );

您的另一个选择是直接将该逻辑放入连接逻辑中。这可能更容易阅读。

SELECT
    lists.ordered,
    cnt1.*
FROM 
    cnt_lists as cnt1
    LEFT JOIN 
        lists
        on 
            cnt1.list_id = lists.id
    LEFT JOIN 
        cnt_lists as cnt2
        on 
            (cnt1.list_id = cnt2.list_id AND (
       (lists.ordered = 1 AND cnt1.id < cnt2.id) OR 
       (lists.ordered = 0 AND cnt1.id > cnt2.id)
    ))

WHERE
    cnt2.id is null and cnt1.list_id in ('3176', '3295', '3296') 
    and cnt1.listable_type = 'Movie'
    ;

您可以选择包含 <在您的最终输出中,但这不会特别有用。

如果您*真的*想要创建动态查询,则很难一步完成,but it is definitely doable .

关于php - MySQL中有没有办法根据CASE动态定义运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40933600/

相关文章:

python - 在 mysql 中自动用虚拟数据填充表

mysql - SQL:获取表摘要/统计信息

MYSQL JOIN同表+COUNT判断排名

cocoa - Cocoa 中等效的 C# 'Thread.Join()' 是什么?

mysql - 对两个 MySQL 查询执行左外连接?

php - 在 PHP 中使用 Javascript 进行表单验证

PHP Include slideshow—不用排队,简单的 css 答案我敢肯定

php - 为什么不重置与 $. Ajax ?

php - TCPDF + TinyMCE + 新的 <strong> 字体

javascript - 以PHP形式以表格方式显示数据