select query based on priority - sql

I have table
Id createdonutc
1 2014-05-29 10:14:00.240
2 2014-05-29 10:16:58.587
3 2014-06-01 11:32:54.140
4 2014-05-29 10:48:40.427
6 2014-06-01 2:1:54.140
I want to get the data with orderby date only(no time) desc
Id createdonutc rank
3 2014-06-01 11:32:54.140 1
6 2014-06-01 2:1:54.140 1
1 2014-05-29 10:14:00.240 2
2 2014-05-29 10:16:58.587 2
4 2014-05-29 10:48:40.427 2
i tried:
SELECT
id,
P.createdonutc,
ROW_NUMBER() OVER (PARTITION BY cast(p.[CreatedOnUtc] AS DATE) ORDER BY cast(p.[CreatedOnUtc] AS DATE) desc) as num
FROM
news p
ORDER BY num
it shows no change on the result.How can i get it to work ?

Please try using DENSE_RANK():
SELECT
id,
P.createdonutc,
Dense_Rank() OVER (ORDER BY cast(p.[CreatedOnUtc] AS DATE) desc) as num
FROM
news p
ORDER BY num

Row_Number generate a different number for every row, even when the values are equal, to get what you want you need to use DENSE_RANK
SELECT id, createdonutc
, dense_rank() OVER (order by cast(createdonutc as date) DESC)
FROM News
SQLFiddle demo

Related

DB2 Toad SQL - Group by Certain Columns using Max Command

I am having some trouble with the below query. I do understand I need to group by ID and Category, but I only want to group by ID while keeping the rest of the columns based on Rank being max. Is there a way to only group by certain columns?
select ID, Category, max(rank)
from schema.table1
group by ID
Input:
ID Category Rank
111 3 4
111 1 5
123 5 3
124 7 2
Current Output
ID Category Rank
111 3 4
111 9 1
123 5 3
124 7 2
Desired Output
ID Category Rank
111 1 5
123 5 3
124 7 2
You can use:
select *
from table1
where (id, rank) in (select id, max(rank) from table1 group by id)
Result:
ID CATEGORY RANK
---- --------- ----
111 1 5
123 5 3
124 7 2
Or you can use the ROW_NUMBER() window function. For example:
select *
from (
select *,
row_number() over(partition by id order by rank desc) as rn
from table1
) x
where rn = 1
See running example at db<>fiddle.
You can try using - row_number()
select * from
(
select ID, Category,rank, row_number() over(partition by id order by rank desc) as rn
from schema.table1
)A where rn=1

SQL : Return joint most frequent values from a column

I have the following table named customerOrders.
ID user order
1 1 2
2 1 3
3 1 1
4 2 1
5 1 5
6 2 4
7 3 1
8 6 2
9 2 2
10 2 3
I want to return to users with most orders. Currently, I have the following QUERY:
SELECT user, COUNT(user) AS UsersWithMostOrders
FROM customerOrders
GROUP BY user
ORDER BY UsersWithMostOrders DESC;
This returns me all the values grouped by total orders like.
user UsersWithMostOrders
1 4
2 4
3 1
6 1
I only want to return the users with most orders. In my case that would be user 1 and 2 since both of them have 4 orders. If I use TOP 1 or LIMIT, it will only return the first user. If I use TOP 2, it will only work in this scenario, it will return invalid data when top two users have different count of orders.
Required Result
user UsersWithMostOrders
1 4
2 4
You can use TOP 1 WITH TIES:
SELECT TOP 1 WITH TIES
[user], COUNT(*) AS UsersWithMostOrders
FROM customerOrders
GROUP BY [user]
ORDER BY UsersWithMostOrders DESC;
See the demo.
Results:
> user | UsersWithMostOrders
> ---: | ------------------:
> 1 | 4
> 2 | 4
Option 1
Should work with most versions of SQL.
select *
from (
select *,
rank() over(order by numOrders desc) as rrank
from (
select `user`, count(*) as numOrders
from customerOrders
group by `user`
) summed
) ranked
where rrank = 1
Play around with the code here
Option 2
If your version of SQL allows window functions (with), here is a much more readable solution which does the same thing
with summed as (
select `user`, count(*) as numOrders
from customerOrders
group by `user`
),
ranked as (
select *,
rank() over(order by numOrders desc) as rrank
from summed
)
select *
from ranked
where rrank = 1
Play around with the code here
You can use a CTE to attain this Req:
;WITH CTE AS(
SELECT [user], COUNT(user) AS UsersWithMostOrders
FROM #T
GROUP BY [user])
SELECT M.* from CTE M
INNER JOIN ( SELECT
MAX(UsersWithMostOrders) AS MaximumOrders FROM CTE) S ON
M.UsersWithMostOrders=S.MaximumOrders
Below Oracle Query can help:
WITH test_table AS
(
SELECT user, COUNT(order) AS total_order , DENSE_RANK() OVER (ORDER BY
total_order desc) AS rank_orders FROM customerOrders
GROUP BY user
)
select * from test_table where rank_orders = 1

Is there a way to get first row of a group in postgres based on Max(date)

Input :
id name value1 value2 date
1 A 1 1 2019-01-01
1 A 2 2 2019-02-15
1 A 3 3 2019-01-15
1 A 1 1 2019-07-13
2 B 1 2 2019-01-01
2 B 1 3 2019-02-15
2 B 2 1 2019-07-13
3 C 2 4 2019-02-15
3 C 1 2 2019-01-01
3 C 1 9 2019-07-13
3 C 3 1 2019-02-15
Expected Output :
id name value1 value2 date
1 A 1 Avg(value2) 2019-07-13
2 B 2 Avg(value2) 2019-07-13
3 C 1 Avg(value2) 2019-07-13
You can use window functions. rank() over() can be used to identify the first record in each group, and avg() over() will give you a window average of value2 in each group:
select id, name, value1, avg_value2 value2, date
from (
select
t.*,
avg(value2) over(partition by id, name) avg_value2,
rank() over(partition by id, name order by date desc) rn
from mytable t
) t
where rn = 1
sort your data in the right way, use the window function row_number() as identifier and select the first entry of every partition.
with temp_data as
(
select
row_number() over (partition by debug.tbl_data.id order by debug.tbl_data.date desc) as index,
*,
avg(debug.tbl_data.value2)over (partition by debug.tbl_data.id) as data_avg
from debug.tbl_data
order by id asc, debug.tbl_data.date desc
)
select
*
from temp_data
where index = 1
You seem to want the most common value of value1. In statistics, this is called the "mode". You can do this as:
select id, name,
mode() within group (order by value1) as value1_mode,
avg(value2),
max(date)
from t
group by id, name;

How to select top 2 values for each id

I have a table with values
id sales date
1 5 "2015-01-04"
1 3 "2015-01-03"
1 1 "2015-01-01"
1 1 "2015-01-01"
2 7 "2015-01-05"
2 6 "2015-01-04"
2 4 "2015-01-03"
3 11 "2015-01-08"
3 10 "2015-01-07"
3 9 "2015-01-06"
3 8 "2015-01-05"
I want to select top two values of each id as shown in desired output.
Desired output:
id sales date
1 5 "2015-01-04"
1 3 "2015-01-03"
2 7 "2015-01-05"
2 6 "2015-01-04"
3 11 "2015-01-08"
3 10 "2015-01-07"
My attempt:
can someone help me with this. Thank you in advance!
select transactions.salesperson_id, transactions.id, transactions.date
from transactions
ORDER BY transactions.salesperson_id ASC, transactions.date DESC;
This can be done using window functions:
select id, sales, "date"
from (
select id, sales, "date",
dense_rank() over (partition by id order by "date" desc) as rnk
from transactions
) t
where rnk <= 2;
If there are multiple rows on the same date this might return more than two rows for the same ID. If you don't want that, use row_number() instead of dense_rank()
row_number() will get what you want.
select * from
(select row_number() over (partition by id order by date) as rn, sales, date from transactions) t1
where t1.rn <= 2

divide data in sql to groups order by another column

I have this set of data
shopId companyId date
1 1 25/8/2015
2 1 26/8/2015
3 1 22/8/2015
4 2 20/8/2015
5 2 27/8/2015
what i need is to get this result
shopId companyId date dense_rank
1 2 27/8/2015 1
2 2 20/8/2015 1
3 1 26/8/2015 2
4 1 25/8/2015 2
5 1 22/8/2015 2
how to get all groups ranked but order with date
SELECT *
, DENSE_RANK() OVER (ORDER BY companyId DESC, [Date] DESC) AS [DENSE_RANK]
FROM TableName
If you want the groups ordered by date, then you need two steps: first get the maximum date for each group. Then use dense_rank():
select shopid, companyid, date,
dense_rank() over (order by maxd desc) as dense_rank
from (select t.*, max(date) over (partition by companyid) as maxd
from table t
) t
Note: this assumes that your date is really stored as a date and not as a string. You will need additional transformations if the data is (improperly) stored as a string.