SQL: Show only the Percentile - sql

I have this working query
SELECT MIN([DealerCode])
,[201309]
,RowNum = Row_Number() OVER(Order By [201309])
,Rnk = RANK() OVER(ORDER BY [201309])
,DenseRnk = DENSE_RANK() OVER(ORDER BY [201309])
,NTile4 = NTILE(100) OVER(ORDER BY [201309])
,BM = RANK() OVER(ORDER BY [201309])*0.7
FROM [SA_Sew].[dbo].[Sew_YTD_Composite$]
where Ratio_ID = 'fi02u' AND DealerCode like '%VW%'
GROUP BY [201309];
How would I be able to get the NTile4 calculation as a field to be able to use it in the Where Field? NTile4 = 70 is benchmark and I need to only see the benchmark.
Thanks!

Write as:
select * from
(
SELECT MIN([DealerCode]) as MinDealerCode
,[201309]
,RowNum = Row_Number() OVER(Order By [201309])
,Rnk = RANK() OVER(ORDER BY [201309])
,DenseRnk = DENSE_RANK() OVER(ORDER BY [201309])
,NTile4 = NTILE(100) OVER(ORDER BY [201309])
,BM = RANK() OVER(ORDER BY [201309])*0.7
FROM [SA_Sew].[dbo].[Sew_YTD_Composite$]
where Ratio_ID = 'fi02u' AND DealerCode like '%VW%'
GROUP BY [201309]
) as T
where NTile4 = 70;

Related

How to get the sum of all values?

select * from
(select * except(rn) from (select sistema_productivo, cod_mpio, periodo,
has_sembrada,has_sembrada_und, id_cultivo,anio, row_number() over(partition by cod_mpio order by
anio desc) rn from TABLENAME where SUBSTR(cod_mpio,1,2) in("23") and sistema_productivo in("ARROZ
SECANO MANUAL", "MAIZ TECNIFICADO") and periodo in("B")) t where rn = 1 and anio =(select max(anio)
as date_max, from (select * except(rn) from (select sistema_productivo, cod_mpio, periodo,
has_sembrada,has_sembrada_und, id_cultivo,anio, row_number() over(partition by cod_mpio order by
anio desc) rn from TABLENAME where SUBSTR(cod_mpio,1,2) in("23") and sistema_productivo in("ARROZ
SECANO MANUAL") and periodo in("B")) t where rn = 1))
)
This query returned
How Can I to get the total sum of has_sembrada from "MAIZ TECNIFICADO" and "ARROZ SECANO MANUAL"
select sistema_productivo, sum(has_sembrada) as total from
(....)
group by sistema_productivo

how to update all rows except first?

I have this sql query :
update CCUSTOMERINFO set VALIDTO=sysdate where (
select * from (
select row_number() over (order by created desc) rn, customer_id, CCUSTOMERINFO.VALIDTO
from CCUSTOMERINFO
where customer_id=100309772 order by created DESC) where rn > 1);
But it say it have some mistake.
This query returns all i want to update :
select * from (
select row_number() over (order by created desc) rn, customer_id, CCUSTOMERINFO.VALIDTO
from CCUSTOMERINFO
where customer_id=100309772 order by created DESC) where rn > 1)
Any suggestion how can i do that?
Use it like the below
update CCUSTOMERINFO set VALIDTO=sysdate where rowid in (
select row_id from (
select row_number() over (order by created desc) rn, customer_id, rowid row_id,
CCUSTOMERINFO.VALIDTO
from CCUSTOMERINFO
where customer_id=100309772 order by created DESC) where rn > 1);

I want to generate continuously number by 2 column and batch wise

I want to generate continuously number with the combination of 2 columns and in batch size of 5. Anybody can help to solve this?
An adoption of #GordonLinoff's answer...
SELECT
name,
rank,
DENSE_RANK() OVER (ORDER BY name DESC, Rank, ((seqnum - 1) / 5)) AS rno
FROM
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY name, rank ORDER BY (SELECT null)) AS seqnum
FROM
yourTable
)
sequenced
ORDER BY
3
You can use row_number() and arithmetic:
select name, rank,
((seqnum - 1) / 5) + 1 as rno
from (select t.*,
row_number() as (partition by name, rank order by (select null)) as seqnum
from t
) t
order by seqnum;

Select max and min values at the same SQL query

I have a SQL table with the columns: ID, ADate, XValue and Type. For each "Type" value, I'd like to retrieve the most recent row (per ADate), the least recent row (per ADate) and also the row containing the highest "XValue" value.
Is it possible to be performed through a single SQL query? I've tried a few times with no success.
Using row_number() you could do something like this:
select ID, ADate, XValue and Type
from (
select *
, min_adate = row_number() over (partition by type order by adate asc)
, max_adate = row_number() over (partition by type order by adate desc)
, max_xvalue = row_number() over (partition by type order by xvalue desc)
from t
) as sub
where 1 in (min_adate,max_adate,max_xvalue)
/* --also could be written as
where min_adate = 1
or max_adate = 1
or max_xvalue = 1
*/
Using a common table expression may make it more readable.
;with cte as (
select *
, min_adate = row_number() over (partition by type order by adate asc)
, max_adate = row_number() over (partition by type order by adate desc)
, max_xvalue = row_number() over (partition by type order by xvalue desc)
from t
)
select ID, ADate, XValue and Type
from cte
where 1 in (min_adate,max_adate,max_xvalue)
select ID, ADate, XValue,[Type]
from (
select *
,row_number() over (partition by type order by adate asc) AS DateSeq
,row_number() over (partition by type) AS TypeCount
,row_number() over (partition by type order by xvalue desc) AS ValueSeq
from t
) as tt
where tt.DateSeq=1 OR tt.DateSeq=tt.TypeCount OR tt.ValueSeq=1
One method uses row_number():
select t.*
from (select t.*,
row_number() over (partition by type order by aDate desc) as seqnum_adate_desc,
row_number() over (partition by type order by aDate asc) as seqnum_adate_asc,
row_number() over (partition by type order by XValue desc) as seqnum_xvalue_desc
from t
) t
where 1 in (seqnum_adate_desc, seqnum_adate_asc, seqnum_xvalue_desc);

Order By Used with Case Statement

i use Order By Used with Case Statement and may be this is the reason for which i am getting error Windowed functions can only appear in the SELECT or ORDER BY clauses.
here is my complete sql where i use Row_Number function for pagination with sorting. please guide me where i made the mistake.
DECLARE #StartIndex INT
DECLARE #EndIndex INT
DECLARE #SortColumn VARCHAR(MAX)
DECLARE #SortDirection VARCHAR(MAX)
SET #StartIndex = 1
SET #EndIndex = 20
SET #SortColumn = 'OrderID'
SET #SortColumn = 'A'
SELECT * FROM Orders
WHERE
ROW_NUMBER() OVER
(
ORDER BY
CASE (#SortColumn + ':' + #SortDirection)
WHEN 'OrderID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'OrderID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
WHEN 'CustomerID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID ASC)
WHEN 'CustomerID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID DESC)
WHEN 'EmployeeID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID ASC)
WHEN 'EmployeeID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID DESC)
WHEN 'OrderDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate ASC)
WHEN 'OrderDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate DESC)
WHEN 'RequiredDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.RequiredDate ASC)
WHEN 'RequiredDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.RequiredDate DESC)
WHEN 'ShippedDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'ShippedDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
WHEN 'ShipVia:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipVia ASC)
WHEN 'ShipVia:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipVia DESC)
WHEN 'Freight:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.Freight ASC)
WHEN 'Freight:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.Freight DESC)
WHEN 'ShipName:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipName ASC)
WHEN 'ShipName:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipName DESC)
WHEN 'ShipAddress:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipAddress ASC)
WHEN 'ShipAddress:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipAddress DESC)
WHEN 'ShipCity:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCity ASC)
WHEN 'ShipCity:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCity DESC)
WHEN 'ShipRegion:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipRegion ASC)
WHEN 'ShipRegion:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipRegion DESC)
WHEN 'ShipPostalCode:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipPostalCode ASC)
WHEN 'ShipPostalCode:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipPostalCode DESC)
WHEN 'ShipCountry:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCountry ASC)
WHEN 'ShipCountry:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCountry DESC)
END
) BETWEEN (#StartIndex - 1) * #EndIndex + 1 AND #StartIndex * #EndIndex
/* AND more conditions ... */
ORDER BY
CASE WHEN #SortDirection = 'A' THEN
CASE #SortColumn
WHEN 'OrderID' THEN OrderID
WHEN 'CustomerID' THEN CustomerID
WHEN 'EmployeeID' THEN CustomerID
WHEN 'OrderDate' THEN CustomerID
WHEN 'RequiredDate' THEN CustomerID
WHEN 'ShippedDate' THEN CustomerID
WHEN 'ShipVia' THEN CustomerID
WHEN 'Freight' THEN CustomerID
WHEN 'ShipName' THEN CustomerID
WHEN 'ShipAddress' THEN CustomerID
WHEN 'ShipCity' THEN CustomerID
WHEN 'ShipRegion' THEN CustomerID
WHEN 'ShipPostalCode' THEN CustomerID
WHEN 'ShipCountry' THEN CustomerID
END
END,
CASE WHEN #SortDirection = 'D' THEN
CASE #SortColumn
WHEN 'OrderID' THEN OrderID
WHEN 'CustomerID' THEN CustomerID
WHEN 'EmployeeID' THEN CustomerID
WHEN 'OrderDate' THEN CustomerID
WHEN 'RequiredDate' THEN CustomerID
WHEN 'ShippedDate' THEN CustomerID
WHEN 'ShipVia' THEN CustomerID
WHEN 'Freight' THEN CustomerID
WHEN 'ShipName' THEN CustomerID
WHEN 'ShipAddress' THEN CustomerID
WHEN 'ShipCity' THEN CustomerID
WHEN 'ShipRegion' THEN CustomerID
WHEN 'ShipPostalCode' THEN CustomerID
WHEN 'ShipCountry' THEN CustomerID
END
END DESC
EDIT 1
i change my code as per your one but still getting same error. here is new code
DECLARE #StartIndex INT
DECLARE #EndIndex INT
DECLARE #SortColumn VARCHAR(MAX)
DECLARE #SortDirection VARCHAR(MAX)
SET #StartIndex = 1
SET #EndIndex = 20
SET #SortColumn = 'CustomerID'
SET #SortDirection = 'D'
;WITH cte as(SELECT *,
ROW_NUMBER() OVER
(ORDER BY
CASE (#SortColumn + ':' + #SortDirection)
WHEN 'OrderID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'OrderID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
WHEN 'CustomerID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID ASC)
WHEN 'CustomerID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.CustomerID DESC)
WHEN 'EmployeeID:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID ASC)
WHEN 'EmployeeID:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.EmployeeID DESC)
WHEN 'OrderDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate ASC)
WHEN 'OrderDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderDate DESC)
WHEN 'RequiredDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.RequiredDate ASC)
WHEN 'RequiredDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.RequiredDate DESC)
WHEN 'ShippedDate:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID ASC)
WHEN 'ShippedDate:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.OrderID DESC)
WHEN 'ShipVia:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipVia ASC)
WHEN 'ShipVia:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipVia DESC)
WHEN 'Freight:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.Freight ASC)
WHEN 'Freight:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.Freight DESC)
WHEN 'ShipName:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipName ASC)
WHEN 'ShipName:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipName DESC)
WHEN 'ShipAddress:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipAddress ASC)
WHEN 'ShipAddress:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipAddress DESC)
WHEN 'ShipCity:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCity ASC)
WHEN 'ShipCity:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCity DESC)
WHEN 'ShipRegion:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipRegion ASC)
WHEN 'ShipRegion:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipRegion DESC)
WHEN 'ShipPostalCode:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipPostalCode ASC)
WHEN 'ShipPostalCode:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipPostalCode DESC)
WHEN 'ShipCountry:A' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCountry ASC)
WHEN 'ShipCountry:D' THEN ROW_NUMBER() OVER (ORDER BY Orders.ShipCountry DESC)
END
) rn
FROM Orders)
SELECT * FROM cte
WHERE rn BETWEEN (#StartIndex - 1) * #EndIndex + 1 AND #StartIndex * #EndIndex
As you have already figured it out you can not use window function in where clause. Just do it in cte or subquery and then filter it outside:
;WITH cte as(SELECT *,
ROW_NUMBER() OVER
(ORDER BY CASE WHEN (#SortColumn + ':' + #SortDirection) = 'OrderID:A'
THEN Orders.OrderID ASC END,
CASE WHEN (#SortColumn + ':' + #SortDirection) = 'OrderID:D'
THEN Orders.OrderID DESC END,
...) rn
FROM Orders)
SELECT * FROM cte
WHERE rn BETWEEN (#StartIndex - 1) * #EndIndex + 1 AND #StartIndex * #EndIndex
/* AND more conditions ... */
ORDER BY
...
--same case expressions here
As you have noticed instead of one big case expression you will have to have many because you can not use different types in one case expressions as you will get conversion errors.
But from my experience it is better to have dynamic sql with parametrised parameters because sql engine will save the execution plans for each case and will be much more quick then having such a big complicated query.
Dynamic version:
DECLARE #sql NVARCHAR(MAX)
SET #sql = ';WITH cte as(SELECT *,
ROW_NUMBER() OVER
(ORDER BY ' + CASE (#SortColumn + ':' + #SortDirection)
WHEN 'OrderID:A' THEN 'Orders.OrderID ASC'
WHEN 'OrderID:D' THEN 'Orders.OrderID DESC'
...
WHEN 'ShipCountry:D' THEN 'Orders.ShipCountry DESC' END +
') rn
FROM Orders)
SELECT * FROM cte
WHERE rn BETWEEN ' + CAST((#StartIndex - 1) * #EndIndex + 1 AS NVARCHAR(MAX)) + ' AND ' +
CAST(#StartIndex * #EndIndex AS NVARCHAR(MAX))
EXEC(#sql)