带分页表和排序的SQL分页查询

时间:2018-05-17 12:42:19

标签: mysql sql sql-server oracle11g db2

我想在需要连接表和排序时共享一些我用于分页的SQL查询。 在这些示例中,结果集限于行号2-3。

MySql 5.1:

SELECT outerO.Id, outerO.Value 
FROM MyTable outerO 
WHERE outerO.id IN (
  SELECT DISTINCT o.id FROM MyTable o  
  JOIN LinkTable l ON l.Fk = o.Id 
  WHERE o.Value LIKE ? ESCAPE '!'
) 
ORDER BY outerO.Value DESC, outerO.Id ASC 
LIMIT 2 
OFFSET 1

这个展示了我想要实现的目标。 Oracle 11和DB2要复杂得多。

Oracle 11:

SELECT outerO.Id, outerO.Value 
FROM MyTable outerO 
WHERE outerO.id IN (
  SELECT id FROM( 
    SELECT row_.id, rownum rownum_ 
    FROM (
      SELECT id 
      FROM (
        SELECT DISTINCT o.Value, o.Id 
        FROM MyTable o  
        JOIN LinkTable l ON l.Fk = o.Id 
        WHERE o.Value LIKE ? ESCAPE '!' 
        ORDER BY o.Value DESC, o.Id ASC
      )
    ) row_ WHERE rownum <= 3
  ) WHERE rownum_ > 1
) 
ORDER BY outerO.Value DESC, outerO.Id ASC

我发现没有办法用更少的子选择来做到这一点。

DB2 10.5:

SELECT outerO.Id, outerO.Value 
FROM MyTable outerO 
WHERE outerO.id IN (
  SELECT inner1_.id 
  FROM (
    SELECT inner2_.id, rownumber() 
    OVER(ORDER BY ORDER OF inner2_) AS rownumber_ 
    FROM (
      SELECT id 
      FROM (
        SELECT DISTINCT o.Value, o.Id 
        FROM MyTable o  
        JOIN LinkTable l ON l.Fk = o.Id 
        WHERE o.Value LIKE ? ESCAPE '!' 
        ORDER BY o.Value DESC, o.Id ASC
      ) 
      FETCH FIRST 3 ROWS ONLY
    ) AS inner2_
  ) AS inner1_ 
  WHERE inner1_.rownumber_ > 1 ORDER BY inner1_.rownumber_
) 
ORDER BY outerO.Value DESC, outerO.Id ASC

我发现没有办法用更少的子选择来做到这一点。

Microsoft SQL-Server 2016:

SELECT outerO.Id, outerO.Value 
FROM MyTable outerO 
WHERE outerO.id IN (
  SELECT DISTINCT o.id 
  FROM MyTable o  
  JOIN LinkTable l ON l.Fk = o.Id 
  WHERE o.Value LIKE ? ESCAPE '!'
) 
ORDER BY outerO.Value DESC, outerO.Id ASC 
OFFSET 1 ROWS 
FETCH NEXT 2 ROWS ONLY

这些查询对我有用,但也许有更好的解决方案可用?

1 个答案:

答案 0 :(得分:1)

这就是我在DB2中的方法

SELECT ID, VALUE
FROM (
  SELECT ID, VALUE, 
         ROW_NUMBER() OVER (ORDER BY o.Value DESC, o.Id ASC) AS RN
  FROM MyTable
  JOIN LinkTable l ON l.Fk = o.Id 
  WHERE o.Value LIKE ? ESCAPE '!' 
  ORDER BY o.Value DESC, o.Id ASC
) X
WHERE RN > 1 AND RN <= 3