Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have OFFSET/FETCH and WITH TIES together?

OFFSET FETCH does not support a logical equivalent to TOP (n) WITH TIES option, which ensures determinism by returning all ties.

Is there any workaround to have OFFSET FETCH and WITH TIES together?

Create statement with sample data

CREATE TABLE #tbl(Id INT, Name VARCHAR(10))

INSERT #tbl
    SELECT 1, 'a' UNION ALL
    SELECT 1, 'a' UNION ALL
    SELECT 2, 'b' UNION ALL
    SELECT 2, 'b' UNION ALL
    SELECT 2, 'b' UNION ALL
    SELECT 3, 'c' UNION ALL
    SELECT 3, 'c' UNION ALL
    SELECT 3, 'c'

TOP

SELECT TOP 3 * FROM #tbl ORDER BY Id

Id  Name
1   a
1   a
2   b

TOP n WITH TIES

SELECT TOP 3 WITH TIES * FROM #tbl ORDER BY Id

Id  Name
1   a
1   a
2   b
2   b
2   b

OFFSET FETCH

SELECT *
FROM #tbl
ORDER BY Id
OFFSET 0 ROWS
FETCH NEXT 3 ROWS ONLY

Id  Name
1   a
1   a
2   b

Probably we need to use Ranking function to achieve this??

like image 259
sqluser Avatar asked Jul 20 '15 07:07

sqluser


People also ask

Can we use fetch without offset?

OFFSET and FETCHYou can use OFFSET without FETCH, but FETCH can't be used by itself. Regardless, OFFSET must be used with an ORDER BY clause.

What is fetch offset?

The FETCH and OFFSET clauses in SQL Server are used in combination with the SELECT and ORDER BY clauses to limit the range of records returned by the query. It was first introduced with the SQL Server version 2012 for doing pagination of the result set. It is useful when our database contains a huge amount of data.

How can use limit and offset in SQL Server?

Limit with offset to select 11 to 20 rows in SQL Server: SELECT email FROM emailTable WHERE user_id=3 ORDER BY Id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; ORDER BY : required. OFFSET : optional number of skipped rows.


1 Answers

Just use them together without FETCH statement inside the CTE

;WITH cte AS
 (
  SELECT Id, Name
  FROM #tbl
  ORDER BY Id
  OFFSET 0 ROWS
  )
  SELECT TOP 3 WITH TIES *
  FROM cte
  ORDER BY Id

See SQLFiddle

Example with offset 3 SQLFiddle

;WITH cte AS
 (
  SELECT Id, Name
  FROM #tbl
  ORDER BY Id
  OFFSET 3 ROWS
  )
  SELECT TOP 3 WITH TIES *
  FROM cte
  ORDER BY Id
like image 132
Aleksandr Fedorenko Avatar answered Oct 07 '22 01:10

Aleksandr Fedorenko