Custom pagination in Oracle - sql

Can anyone suggest whether the below query format is correct?
SELECT *
FROM ( SELECT b.*
, ROW_NUMBER() OVER (Order by b.TEST_NO) R
FROM ( select r.*
from ( select TEST_NO , TEST_NO1, TEST_NO2
From test_table
where TEST_NO2 = '0000as23') r
where 1 = 1
and rownum < 10000 ) b
)
WHERE R BETWEEN 11 and 200;
Here I am trying to achieve custom pagination using Oracle syntax.

Related

SQL Unique ID for union all - Sybase

Is it possible to generate a unique ID for the auxiliary table? I am retrieving data from several tables, but I do not know how to create a new ID for the results:
I would like to have an additional column with ID.
I tried to look for several methods, but nothing helped me.
I will be very grateful.
Greetings,
with ct as (
select *
INTO temp_table
from dba.view_NEW_Users_AreaCodes ur
join dba.view_NEW_Customers_SalesTowns ct on ct.CustSalesTerritoryTTID = ur.UserAreaCodeID
where ur.UserType = 'TT'
and ct.CustSalesTerritoryTTID <> 0
union all
select *
from dba.view_NEW_Users_AreaCodes ur
join dba.view_NEW_Customers_SalesTowns ct on ct.CustSalesTerritoryMTID = ur.UserAreaCodeID
where ur.UserType = 'MT'
and ct.CustSalesTerritoryMTID <> 0
union all
select *
from dba.view_NEW_Users_AreaCodes ur
join dba.view_NEW_Customers_SalesTowns ct on ct.CustSalesTerritoryHRCID = ur.UserAreaCodeID
where ur.UserType = 'HRC'
and ct.CustSalesTerritoryHRCID <> 0
union all
select *
from dba.view_NEW_Users_AreaCodes ur
join dba.view_NEW_Customers_SalesTowns ct on ct.CustSalesTerritoryDevID = ur.UserAreaCodeID
where ur.UserType = 'DEV'
and ct.CustSalesTerritoryDevID <> 0
)
select row_number() over (order by newid()) as DATA_ID,
ct.*
from ct;
You could use row_number():
with t as (
< your query here >
)
select row_number() over (order by newid()) as seqnum,
t.*
from t;
newid() is just an arbitrary value that randomizes the numbering. You can use a column there if you prefer a more canonical ordering.

How to call a sql query and pass a parameter from another table?

I have a complex sql query, named qryARAT2B_EXT.
SELECT
*
FROM
(
SELECT
*
FROM
(
SELECT
*,
firstStudy,
ABS(DATEDIFF('d', firstStudy, Check_Date)) as diff
FROM
(
SELECT
*,
(
SELECT
TOP 1 Check_Date
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
ORDER BY
Check_Date
)
AS firstStudy
FROM
(
SELECT
*
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
)
AS myPatientsWithStudy
)
AS myPatientsFirstStudy
)
WHERE
diff = 0
)
AS T1
LEFT JOIN
(
SELECT
*
FROM
(
SELECT
*,
firstStudy,
ABS(DATEDIFF('d', firstStudy, Check_Date)) as diff
FROM
(
SELECT
*,
(
SELECT
TOP 1 Check_Date
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
ORDER BY
Check_Date
)
AS firstStudy
FROM
(
SELECT
*
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
)
AS myPatientsWithStudy
)
AS myPatientsFirstStudy
)
WHERE
diff = 4
)
As T2
ON T1.PATNR = T2.PATNR
When I open it in ms-access, it asks for the value of the [PARAM] and produces the result.
I have a table of patients.
tblPatient with the columns:
PATNR, and s.o.
That contains the PATNR's of patients:
000001
000002
...
XXXXXX
I need to write sql to calculate data for all PATNR's at once.
something like this:
SELECT (SELECT * FROM qryARAT2B_EXT WHERE [PARAM] = PATNR) from tblPatient
But it is not accepted from ms-access. I'm not able to pass parameter to qryARAT2B_EXT from the SQL. Is there any specific syntax for it in ms-access?

SQL Server select queries union all and limit

I have a lot of problems to migrate queries from Mysql to SQL Server. I have this query that is a bit complicated but in mysql it works fine.
I have a select from a table union all to a select from another table not equals and a limit to paginate the results because the rows returned are a lot. When I tried to migrate to SQL Server, the selects with the union work fine. When I read how to implement a limit in T-SQL, in stackoverflow and another pages I learned how to do but when I try to apply it to my query it does not run and SQL Server returns an error.
The query without limit is the following (this query works well):
SELECT
'false' AS historico,
'' AS tabla,
a.nombre,
a.apellido1,
a.apellido2
FROM
persons a
WHERE
a.eliminado = 'N'
AND (idconv = 30)
UNION ALL
SELECT
'true' AS historico,
b.tabla,
b.nombre,
b.apellido1,
b.apellido2
FROM
persons_hist b
WHERE
b.eliminado = 'N'
AND (tabla = '1955')
ORDER BY
apellido1 ASC
but when I try to add "pagination" for example 10 rows starting in 0 this query returns me 18 rows 9 rows from the first table and 9 rows from the second table, but I have to paginate for example 10 rows from the union of 2 tables.
;WITH Results_CTE AS
(
select
ROW_NUMBER() OVER (ORDER BY apellido1 asc ) AS RowNum ,
'false' as historico,
'' as tabla,
a.nombre, a.apellido1, a.apellido2
from
persons a
where
a.eliminado = 'N' and (idconv = 30)
union all
select
ROW_NUMBER() OVER (ORDER BY apellido1 asc ) AS RowNum ,
'true' as historico,
b.tabla, b.nombre, b.apellido1, b.apellido2
from
persons_hist b
where
b.eliminado = 'N' and (tabla = '1997')
)
SELECT *
FROM Results_CTE
WHERE RowNum >= 0
AND RowNum < 0 + 10
Can somebody please help me?
one problem is that SQL SERVER row_number starts at 1 - you do not get a 0, so you have asked for 0 - 9 which will be 9 rows/
your other problem seems to be that row_number is calculated separately for each part of the UNION (which is logical for it to do so) - try calculating row number in a 2nd CTE
try
;WITH Results_CTE1 AS
(
select 'false' as historico,'' as tabla,a.nombre,a.apellido1,a.apellido2 from persons a where a.eliminado = 'N' and ( idconv = 30 )
union all
select 'true' as historico,b.tabla,b.nombre,b.apellido1,b.apellido2 from persons_hist b
where b.eliminado = 'N' and ( tabla = '1997' )
),
Results_CTE AS
(
SELECT *,ROW_NUMBER() OVER (ORDER BY apellido1 asc ) AS RowNum FROM Results_CTE1
)
SELECT *
FROM Results_CTE
WHERE RowNum BETWEEN 1 AND 10
You have 2 separate rownumbers in here. Try this:
WITH Results_CTE AS
(
'false' as historico,'' as tabla,a.nombre,a.apellido1,a.apellido2 from persons a where a.eliminado = 'N' and ( idconv = 30 )
union all
'true' as historico,b.tabla,b.nombre,b.apellido1,b.apellido2 from persons_hist b
where b.eliminado = 'N' and ( tabla = '1997' )
)
select *
from
(
select CTE1.*, row_number() over (order by apellido1 ) as RowNum
from Results_CTE
)
where RowNum <=10

Efficient way to write this query

I am trying to order the records by 3 columns and then select a particular ID and the record before that plus the row after that. Here is my query:
;With Cte As
(
SELECT ROW_NUMBER() Over(Order By Book, PageINT, [IDAuto]) as RowNum, [IdAuto]
FROM CCWiseInstr2
)
Select * From Cte
Where RowNum = (Select RowNum From Cte
Where IdAuto = 211079)
UNION
Select * From Cte
Where RowNum = (Select RowNum - 1 From Cte
Where IdAuto = 211079)
UNION
Select * From Cte
Where RowNum = (Select RowNum + 1 From Cte
Where IdAuto = 211079)
What could the other efficient way to write this query. At the moment the query takes about 336 ms after creating all indexes which looks like a bit higher to me.
Here is the plan for the query:
http://gyazo.com/9a7f1c37d4433665d0949acf03c4561c
Any help is appreciated.
How about this query:
;With Cte As
(
SELECT ROW_NUMBER() Over(Order By Book, PageINT, [IDAuto]) as RowNum, [IdAuto]
FROM CCWiseInstr2
)
Select RowNum, IDAuto From Cte
Where RowNum IN (
Select RowNumber From
(
Select RowNum - 1 as RowNumPrev,
RowNum as RowNum,
RowNum + 1 as RowNumNext
From Cte
Where IdAuto = 211079
) vw unpivot (
RowNumber For
IdAuto IN (RowNumPrev, RowNum, RowNumNext )
) unpw )
Instead of UNION just use UNPIVOT which will convert your columns into rows which you could then use in IN. Let me know how it goes.
You can use the LEAD and LAG functions with SQL Server. Here's a great article on Simple Talk covering all of the options. (Code below is untested)
https://www.simple-talk.com/sql/t-sql-programming/sql-server-2012-window-function-basics/
SELECT
[IdAuto],
LAG([IDAuto], 1) OVER(Order By Book, PageINT, [IDAuto]) AS PreviousSale,
LEAD([IDAuto], 1) OVER(Order By Book, PageINT, [IDAuto]) AS NextSale
FROM
CCWiseInstr2
WHERE [IdAuto] = 211079;

oracle query returns 4 duplicates of each row

I am running an Oracle query. It seems to work except that it returns 4 duplicates of each result. Here is the query:
Select * from (
Select a.*, rownum rnum From (
SELECT NEW_USER.*, NEW_EHS_QUIZ_COMPLETE.datetime
FROM NEW_USER, NEW_EHS_QUIZ_COMPLETE
WHERE EXISTS (
select *
from NEW_EHS_QUIZ_COMPLETE
where NEW_USER.id=NEW_EHS_QUIZ_COMPLETE.USER_ID
)
ORDER by last_name ASC
) a
where rownum <= #pgtop#
)
where rnum >= #pgbot#
Does anyone know why this isn't working properly?
You have a cross join here:
SELECT
NEW_USER.*,
NEW_EHS_QUIZ_COMPLETE.datetime
FROM NEW_USER, NEW_EHS_QUIZ_COMPLETE
WHERE EXISTS(
select * from NEW_EHS_QUIZ_COMPLETE
where NEW_USER.id=NEW_EHS_QUIZ_COMPLETE.USER_ID
)
You probably mean this:
SELECT
NEW_USER.*,
NEW_EHS_QUIZ_COMPLETE.datetime
FROM NEW_USER
INNER JOIN NEW_EHS_QUIZ_COMPLETE
ON NEW_USER.id = NEW_EHS_QUIZ_COMPLETE.USER_ID