split row_number() over partition over multiple columns - sql

I have a query which uses row_number() over partition.
When the result comes out it looks like
Product Row_Number Price
A 1 25
A 2 20
A 3 15
B 1 100
B 2 10
B 3 2
I want to get the result to show over columns like
Product Row1 Row2 Row3 price1 price2 price3
A 1 2 3 25 20 15
B 1 2 3 100 10 2
Should I use something like rank()???
I'm using Teradata

You can add two more window functions to get the 2nd and 3rd highest price, this should run in the same STAT-step as your current ROW_NUMBER, so there's no additional overhead:
select
product,
price as Price1,
min(price)
over (partition by product
order by price desc
rows between 1 following and 1 following) as Price2,
min(price)
over (partition by product
order by price desc
rows between 2 following and 2 following) as Price3
from tab
qualify
row_number()
over (partition by product
order by price desc) = 1

I just give sort direction for each sort parameter , and then , it works , very fine. No Partition is used.
SELECT TOP (5) ROW_NUMBER() OVER (ORDER BY SCHEME ASC,APPLICATION_DATE DESC,TRANSACTION_REF_NO ASC,APPLICATION_STATUS DESC)

Related

selecting the first and last 10 rows of a sql query

hi i have a sqlite database like this
price category_id product_id
100000 89 1
2000 88 2
50000 89 3
i want to extract the top and last 5 of product id for each category (the highest and lowest products of each category)
i have written this
SELECT *
FROM sql_data_users.products
GROUP BY product_id,category_id
ORDER BY price ASC
LIMIT 10
but it gives me 10 rows instead of 10*len(category_id)
also for the solution to be complete i thought of adding another query and changeing the order to ASC and then uniting the 2 query is that possible and how?
You would use window functions:
select t.*
from (select t.*,
row_number() over (partition by category order by price asc) as seqnum_asc,
row_number() over (partition by category order by price desc) as seqnum_desc
from t
) t
where seqnum_asc <= 5 or seqnum_desc <= 5
order by category, price desc;

SQL Split One Row To Multiple Rows Based on Column Number

I have an order table and I will keep it simple. I need to split the rows based on the quantity in the order. For example, if an order quantity is 4 I need to split the original rows into 4 rows with quantity of 1 each. Example data below.
ID FKID Product QTY
1 100 Widget 4
I need a result like this.
ID FKID Product QTY
1 100 Widget 1
2 100 Widget 1
3 100 Widget 1
4 100 Widget 1
Just another option using an ad-hoc tally table and a simple JOIN
Example
Select ID = row_number() over (partition by A.ID order by N)
,FKID
,Product
,Qty = 1
From YourTable A
Join (
Select Top (1000) N=Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ,master..spt_values n2
) B on N<=A.[QTY]
Returns
ID FKID Product Qty
1 100 Widget 1
2 100 Widget 1
3 100 Widget 1
4 100 Widget 1
One simple method is a recursive CTE:
with cte as (
select ID, FKID, Product, QTY
from t
union all
select ID, FKID, Product, QTY - 1
from t
where qty > 1
)
select id, fkid, product, 1 as qty
from cte;
The only caveat is that if qty can be 100 or greater, you'll need option (maxrecursion 0).

How to find row with equal value?

I've got a table Accounts
AMOUNT| ID_CLIENT | ID_BRANCH
250 1 1
250 1 3
100 1 4
300 2 1
300 2 3
450 3 2
100 3 2
225 4 1
225 4 2
225 4 4
225 4 5
I need to find clients who have the same amount in every branch (like ID_CLIENT = 2 and ID_CLIENT = 4). I have no idea how can I implement this ( Could anyone help me, please?
Use two levels of aggregation:
select client
from (select client, branch, sum(amount) as amount
from t
group by client, branch
) cb
group by client
having min(amount) = max(amount);
I can't tell if you can have multiple rows per client/branch. If not, you just need:
select client
from t
group by client
having min(amount) = max(amount);
You can use analytical functions to achieve the same:
Demo
with CTE1 as
(
SELECT A.*, DENSE_RANK() OVER (PARTITION BY ID_CLIENT ORDER BY AMOUNT) DN,
COUNT(*) OVER (PARTITION BY ID_CLIENT) TOTAL_COUNT
FROM TABLE1 A ORDER BY ID_CLIENT
)
SELECT ID_CLIENT FROM
(
SELECT ID_CLIENT, SUM(DN), TOTAL_COUNT
FROM CTE1
GROUP BY ID_CLIENT, TOTAL_COUNT
HAVING SUM(DN) = TOTAL_COUNT
);
By using First_value and Last_value:
Demo
SELECT DISTINCT ID_CLIENT FROM
(
SELECT A.*,
FIRST_VALUE(AMOUNT) OVER(PARTITION BY ID_CLIENT ORDER BY AMOUNT ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FST_VAL,
LAST_VALUE(AMOUNT) OVER(PARTITION BY ID_CLIENT ORDER BY AMOUNT ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) LST_VAL
FROM TABLE1 A
) X WHERE FST_VAL = LST_VAL ;

How would you retrieve an entire column

ID Name Price
--------------------------------------
1 item1 10
2 item2 40
3 item3 10
4 item4 20
5 item5 50
6 item6 20
Say you had this table above and wanted to retrieve the following:
ID Name Price
5 item5 50
But you wanted to retrieve the above by using the highest price. I am currently using the below code.
SELECT
MAX(price) AS Price,
Name,
ID
FROM
ExampleTable
GROUP BY
Name, ID;
In SQL Server we can try:
SELECT TOP 1 *
FROM yourTable
ORDER BY Price DESC;
If there could be more than one record tied for the highest price, and you also wanted to report all ties, then we could use WITH TIES:
SELECT TOP 1 WITH TIES *
FROM yourTable
ORDER BY Price DESC;
If you want to use TOP to select only certain columns, then just list those columns out, e.g.
SELECT TOP 1 ID, Price
to select only the ID and Price columns.
use top as your DBMS is sql server
select top 1 * from your_table
order by Price desc
You could also use window function
with t1 as
(
select * , row_number() over(order by Price desc) as rn from your_table
) select ID ,Name ,Price from t1 where rn=1

SQL Max over multiple versions

I have a table with three columns
Product Version Price
1 1 25
1 2 15
1 3 25
2 1 8
2 2 8
2 3 4
3 1 25
3 2 10
3 3 5
I want to get the max price and the max version by product.
So in the above example the results would have product 1, version 3, price25. product 2, version 2, price 8.
Can you let me know how I would do this.
I'm on Teradata
If Teradata supports the ROW_NUMBER analytic function:
SELECT
Product,
Version,
Price
FROM (
SELECT
atable.*, /* or specify column names explicitly as necessary */
ROW_NUMBER() OVER (PARTITION BY Product
ORDER BY Price DESC, Version DESC) AS rn
FROM atable
) s
WHERE rn = 1
;
Using Teradata SQL this can be further simplified:
SELECT * FROM atable
QUALIFY
ROW_NUMBER()
OVER (PARTITION BY Product
ORDER BY Price DESC, Version DESC) = 1;
The QUALIFY is a Teradata extension to Standard SQL, it's similar to a HAVING for GROUP BY, it filters the result of a window function.
SELECT product
, max(version) as version
, max(price) as price
FROM mytable
GROUP BY product
Following code will select product, Highest value of version, Highest value of price and will sort at product using GROUP BY
SELECT [product], MAX([version]) as [MaxVersion], MAX([price]) as [MaxPrice]
FROM [NameOfTable]
GROUP BY [product]
More explanation on Max function:
Max function SQL
try this one
select p.Product, MAX(p.Price), (select MAX(Version) from Products where Product = p.Product and Price = MAX(p.price))
from Products as p
group by p.Product
it returns
(Product, price,version)
1 25 3 ,
2 8 2 ,
3 25 1