我有以下MySQL查询,我已经工作了一段时间。我想在list_id
语句中为每个in
获取一条唯一记录。我正在加入表格并检查lists.ordered
表以确定是否需要获取第一个或最后一个订单项。
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 = 'App\\Models\\Movie';
抓住最后一项是很好的,但是当我尝试抓住第一个订单项时,它实际抓住了第二个项目。
有人有任何建议吗?
示例数据:
id list_id listable_id listable_type order created_at updated_at
2226 3296 7 App\Models\Movie 1 2016-12-02 12:56:29 2016-12-02 15:07:42
2224 3296 1 App\Models\Movie 2 2016-11-29 00:06:57 2016-12-02 15:07:42
2227 3296 9 App\Models\Movie 3 2016-12-02 12:56:35 2016-12-02 12:56:35
2228 3296 54 App\Models\Movie 4 2016-12-02 12:56:39 2016-12-02 12:56:39
2229 3296 40 App\Models\Movie 5 2016-12-02 12:56:43 2016-12-02 12:56:43
2230 3296 65 App\Models\Movie 6 2016-12-02 12:56:47 2016-12-02 12:56:47
在上面的示例中,如果lists.ordered = 0
它会抓住行2230
,因为它是最高order
。如果lists.ordered = 1
它会抓住行2226
,因为它是最低order
。最高的工作正常,但最低的是抓住2224
,这是第二低的。
答案 0 :(得分:2)
不要尝试在单个SQL中执行此操作。相反,编写应用程序代码或存储过程以在“第一个”和“最后一个”之间进行选择。
甚至比这更简单:
SELECT ... FROM ...
ORDER BY ordered ASC -- ASC gives #1; DESC gives #6 in the example
LIMIT 1;
如果输出多行,则可能需要Groupwise max问题。
好的,在一个声明中有一种混乱的方式:
( SELECT 0 AS which, ... ORDER BY ordered ASC LIMIT 1 )
UNION ALL
( SELECT 1 AS which, ... ORDER BY ordered DESC LIMIT 1 )
HAVING which = (however you pick first vs last);
答案 1 :(得分:1)
您希望找到order
列排序的第1行/最后一行,但您是否在id
列上进行了排序?在这种情况下,试试这个:
SELECT lists.ordered,
CNT1。*
来自cnt_lists AS cnt1
LEFT JOIN列表
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.order &lt; cnt2.order )
或(lists.ordered = 0
AND cnt1.order &gt; cnt2.order )))
在哪里cnt2.id IS NULL
AND cnt1.list_id IN(&#39; 3176&#39;,&#39; 3295&#39;,&#39; 3296&#39;)
AND cnt1.listable_type =&#39; App \ Models \ Movie&#39 ;;