There are 25 records in this sql query
I want to get between 5 and 10. How can I do it ?
I use 11g
select
(
select count(*) as sayfasayisi
from konular t
where t.kategori is not null
) as sayfasayisi,
t.id,
t.uye,
t.baslik,t.mesaj,t.kategori,t.tarih,
t.edittarih,t.aktif,t.indirimpuani,t.altkategori,t.link,
nvl(
(select case when t.id = f.konuid and f.uye = 'test' then '1' else '0' end
from takipkonu f where t.id = f.konuid and f.uye = 'test'), '0') as takip
from konular t
where t.kategori is not null
You can use ROW_NUMBER() to assign a row number based on some ordering logic contained in your current query, e.g. a certain column. Then, retain only the 5th to 10th records:
select t.*
from
(
select
(
select count(*) as sayfasayisi
from konular t
where t.kategori is not null
) as sayfasayisi,
ROW_NUMBER() OVER (ORDER BY some_col) rn,
t.id,
t.uye,
...
) t
where t.rn between 5 and 10;
Related
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.
I have a Oracle table with the following columns
Table Structure
In a query I need to return all the records with CPER>=40 which is trivial. However, apart from CPER>=40 I need to list 5 random records for each CPID.
I have attached a sample list of records. However, in my table I have around 50,000 records.
Appreciate if you can help.
Oracle solution:
with CTE as
(
select t1.*,
row_number() over(order by DBMS_RANDOM.VALUE) as rn -- random order assigned
from MyTable t1
where CPID <40
)
select *
from CTE
where rn <=5 -- pick 5 at random
union all
select t2.*, null
from my_table t2
where CPID >= 40
SQL Server:
with CTE as
(
select t1.*,
row_number() over(order by newid()) as rn -- random order assigned
from MyTable t1
where CPID <40
)
select *
from CTE
where rn <=5 -- pick 5 at random
union all
select t2.*, null
from my_table t2
where CPID >= 40
How about something like this...
SELECT *
FROM (SELECT CID,
CVAL,
CPID,
CPER,
Row_number() OVER (partition BY CPID ORDER BY CPID ASC ) AS RN
FROM Table) tmp
WHERE CPER>=40 OR pids <= 5
However, this is not random.
Assuming that you want five additional random records, you can do:
select t.*
from (select t.*,
row_number() over (partition by cpid,
(case when cper >= 40 then 1 else 2 end)
order by dbms_random.value
) as seqnum
from t
) t
where seqnum <= 5 or cper >= 40;
The row_number() is enumerating the rows for each cpid in two groups -- based on the cper value. The outer where is taking all cper values in the range you want as well as five from the other group.
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
How can I find maximum value on multiple columns.
This is what I have so far.
With Temp AS (
SELECT P.ID AS 'Product_ID',
P.ProductCode AS 'Product_Code',
P.Name AS 'Product_Name',
P.SellPrice AS 'SellPrice',
P.SellPrice+(P.SellPrice*TVA/100) AS 'PricePerUnit',
P.TVA AS 'TVA',
P.Discount AS 'Discount_Product',
0 AS 'Discount_Code',
0 AS 'Discount_Newsletter',
V.ID AS 'Variant_ID',
V.Nume AS 'Variant_Name',
V.Stock-V.Reserved AS 'Quantity_MAX',
T.Quantity AS 'Quantity',
I.ImageName AS 'Image',
0 AS 'Is_Kit'
FROM TemporaryShoppingCart T
INNER JOIN ProductVariant V ON V.ID=T.Variant_ID
INNER JOIN Product P ON P.ID=V.ProductID
LEFT JOIN ProductImage I ON I.ProductID=P.ID AND DefaultImage=1
WHERE T.ID=#ID AND T.Variant_ID!=0
) SELECT t.* ,MAX(MAXValue) FROM (SELECT (T.Discount_Product) AS 'MAXValue'
UNION ALL
SELECT (T.Discount_Code)
UNION ALL
SELECT (T.Discount_Newsletter)) as 'maxval' //error
FROM Temp T
This code is giving me the error: Incorrect syntax near 'maxval'.
Are you simply looking for GREATEST?
SELECT
t.*,
GREATEST(T.Discount_Product, T.Discount_Code, T.Discount_Newsletter) as 'maxval'
FROM Temp T;
However GREATEST Returns NULL when a value is NULL, so you might want to care about this, too. For instance:
SELECT
t.*,
GREATEST
(
coalesce(T.Discount_Product,0),
coalesce(T.Discount_Code, 0),
coalesce(T.Discount_Newsletter, 0)
) as 'maxval'
FROM Temp T;
EDIT: In case GREATEST is not available in your dbms you can use a case expression.
SELECT
t.*,
CASE
WHEN coalesce(T.Discount_Product, 0) > coalesce(T.Discount_Code, 0)
AND coalesce(T.Discount_Product, 0) > coalesce(T.Discount_Newsletter, 0)
THEN coalesce(T.Discount_Product, 0)
WHEN coalesce(T.Discount_Code, 0) > coalesce(T.Discount_Product, 0)
AND coalesce(T.Discount_Code, 0) > coalesce(T.Discount_Newsletter, 0)
THEN coalesce(T.Discount_Code, 0)
ELSE coalesce(T.Discount_Newsletter, 0)
END
FROM Temp T;
EDIT: To get your own statement syntactically correct, do:
SELECT
t.*,
(
select MAX(Value)
FROM
(
SELECT T.Discount_Product AS Value
UNION ALL
SELECT T.Discount_Code
UNION ALL
SELECT T.Discount_Newsletter
) dummy -- T-SQL requires a name for such sub-queries
) as maxval
FROM Temp T;
You probably want to have each Select statement to have a From clause.
SELECT max( GREATEST(col1,col2, col3,col4, col5, col6, col7, col8, col9,col10, col11, col12)) AS 'MAXDATE' FROM table_name
Consider we have three tables C1,C2 and C3.
The table data are as follow :-
To find the 1st max value we use the following sql query:
Query:
;WITH CTE AS
(
SELECT (T.Marks) AS Highest, ROW_NUMBER() OVER (ORDER BY MAX(T.MARKS) DESC) AS R FROM
(
SELECT (c1.Marks) AS Marks FROM c1
UNION
SELECT (c2.Marks) AS Marks FROM c2
UNION
SELECT (c3.Marks) AS Marks FROM c3
) AS T GROUP BY (T.Marks) )
SELECT Highest FROM CTE WHERE R = 1
To find the next max values change the value of R in last line of query.
I have the following table structure:
Id, Message
1, John Doe
2, Jane Smith
3, Error
4, Jane Smith
Is there a way to get the error record and the surrounding records? i.e. find all Errors and the record before and after them.
;WITH numberedlogtable AS
(
SELECT Id,Message,
ROW_NUMBER() OVER (ORDER BY ID) AS RN
FROM logtable
)
SELECT Id,Message
FROM numberedlogtable
WHERE RN IN (SELECT RN+i
FROM numberedlogtable
CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n
WHERE Message='Error')
WITH err AS
(
SELECT TOP 1 *
FROM log
WHERE message = 'Error'
ORDER BY
id
),
p AS
(
SELECT TOP 1 l.*
FROM log
WHERE id <
(
SELECT id
FROM err
)
ORDER BY
id DESC
)
SELECT TOP 3 *
FROM log
WHERE id >
(
SELECT id
FROM p
)
ORDER BY
id
Adapt this routine to pick out your target.
DECLARE #TargetId int
SET #TargetId = 3
select *
from LogTable
where Id in (-- "before"
select max(Id)
from LogTable
where Id < #TargetId
-- target
union all select #TargetId
-- "after"
union all select min(Id)
from LogTable
where Id > #TargetId)
select id,messag from
(Select (Row_Number() over (order by ID)) as RNO, * from #Temp) as A,
(select SubRNO-1 as A,
SubRNO as B,
SubRNO+1 as C
from (Select (Row_Number() over (order by ID)) as SubRNO, * from #Temp) as C
where messag = 'Error') as B
where A.RNO = B.A or A.RNO = B.B or A.RNO = B.C
;WITH Logs AS
(
SELECT ROW_NUMBER() OVER (ORDER BY id), id, message as rownum FROM LogTable lt
)
SELECT curr.id, prev.id, next.id
FROM Logs curr
LEFT OUTER JOIN Logs prev ON curr.rownum+1=prev.rownum
RIGHT OUTER JOIN Logs next ON curr.rownum-1=next.rownum
WHERE curr.message = 'Error'
select id, message from tbl where id in (
select id from tbl where message = "error"
union
select id-1 from tbl where message = "error"
union
select id+1 from tbl where message = "error"
)
Get fixed number of rows before & after target
Using UNION for a simple, high performance query (I found selected answer WITH query above to be extremely slow)
Here is a high performance alternative to the WITH top selected answer, when you know an ID or specific identifier for a given record, and you want to select a fixed number of records BEFORE and AFTER that record. Requires a number field for ID, or something like date that can be sorted ascending / descending.
Example: You want to select the 10 records before and after a specific error was recorded, you know the error ID, and can sort by date or ID.
The following query gets (inclusive) the 1 result above, the identified record itself, and the 1 record below. After the UNION, the results are sorted again in descending order.
SELECT q.*
FROM(
SELECT TOP 2
id, content
FROM
the_table
WHERE
id >= [ID]
ORDER BY id ASC
UNION
SELECT TOP 1
id, content
FROM
the_table
WHERE
id < [ID]
ORDER BY id DESC
) q
ORDER BY q.id DESC