簡體   English   中英

MySQL的:從子查詢最大N值排序

[英]Mysql: Order by max N values from subquery

我要把這個扔掉。

前言:我想使用任何N,但為了簡單起見,我將N設置為3。

我有一個查詢(特別是MySQL),該查詢需要從表中提取數據並根據該表中的前3個值進行排序,然后再回退到其他排序條件。

所以基本上我有這樣的事情:

SELECT tbl.id 
FROM
  tbl1 AS maintable 
  LEFT JOIN 
  tbl2 AS othertable 
  ON
  maintable.id = othertable.id
ORDER BY 
  othertable.timestamp DESC, 
  maintable.timestamp DESC

這是所有基本的教科書內容。 但是問題是我需要第一個ORDER BY子句才能僅在othertable.timestamp中獲得三個最大值,然后回退到maintable.timestamp上。

另外,對OTHERtable執行LIMIT 3子查詢並加入它也是不可行的,因為這需要在主表上應用任意數量的WHERE條件。

我幾乎可以使它與基於用戶變量的方法一起使用,但是由於未考慮排序而失敗,因此它將采用找到的其他三個表值:

ORDER BY 
  (
    IF(othertable.timestamp IS NULL, 0, 
      IF(
        (@rank:=@rank+1) > 3, null, othertable.timestamp
      )
    )
  ) DESC

(在語句前加上@rank:= 0)

那么...對此有什么建議嗎? 我對這個問題不知所措。 我為此擁有的另一個參數是,由於僅更改現有(非常復雜)的查詢,因此無法進行包裝外部查詢。 另外,如前所述,我正在使用MySQL,因此不幸的是,任何使用ROW_NUMBER函數的解決方案都無法實現。

在此先感謝所有。

編輯。 這是一些帶有時間戳的示例數據,這些時間戳被精簡為更簡單的整數,以說明我的需求:

maintable

id      timestamp
1       100
2       200
3       300
4       400
5       500
6       600

othertable

id     timestamp
4      250
5      350
3      550
1      700

=>

1
3
5
6
4
2

如果出於任何原因,我們在查詢中添加WHERE NOT maintable.id = 5,那么我們應該得到:

1
3
4
6
2

...因為現在4是其他表引用此集合的前3個值之一。

正如您所看到的,來自othertable的ID為4的行不包含在排序中,因為它是時間戳值降序的第四位,因此它又回到了按基本時間戳排序的位置。

現實世界對此的需求是這樣的:我在“ maintable”中有內容,而“ othertable”基本上是帶有“特征日期”時間戳的特征內容的標記。 我認為應該將最后3個特色商品浮動到頂部,而列表的其余部分只是一個倒序的時間順序列表。

也許是這樣的。

SELECT
  id
FROM
  (SELECT 
    tbl.id,
    CASE WHEN othertable.timestamp IS NULL THEN 
      0 
    ELSE 
      @i := @i + 1
    END AS num,
    othertable.timestamp as othertimestamp,
    maintable.timestamp as maintimestamp
  FROM
    tbl1 AS maintable
    CROSS JOIN (select @i := 0) i 
    LEFT JOIN tbl2 AS othertable 
      ON maintable.id = othertable.id
  ORDER BY
    othertable.timestamp DESC) t
ORDER BY
  CASE WHEN num > 0 AND num <= 3 THEN
    othertimestamp
  ELSE
    maintimestamp
  END DESC

修改后的答案:

select ilv.* from
(select sq.*, @i:=@i+1 rn from
 (select @i := 0) i
  CROSS JOIN 
 (select m.*, o.id o_id, o.timestamp o_t
  from maintable m
  left join othertable o
  on m.id = o.id
  where 1=1
  order by o.timestamp desc) sq
) ilv
order by case when o_t is not null and rn <=3 then rn else 4 end,
         timestamp desc

SQLFiddle 在這里

修改子查詢sq where 1=1條件以匹配所需的復雜選擇條件,並在最終order by之后添加適當的limit條件order by用於分頁要求。

您可以使用以下聯合查詢嗎?

(SELECT id,timestamp,1 AS isFeatured FROM tbl2 ORDER BY timestamp DESC LIMIT 3)
UNION ALL
(SELECT id,timestamp,2 AS isFeatured FROM tbl1 WHERE NOT id in (SELECT id from tbl2 ORDER BY timestamp DESC LIMIT 3))
ORDER BY isFeatured,timestamp DESC

這可能有點多余,但是從語義上講更接近您要提出的問題。 這也將允許您參數化要返回的特色結果的數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM