I'm trying to write a query to solve a logical problem using Redshift POSTGRES 8.
Input column is a bunch of IDs and Order IDs and desired output is basically a rank of the ID as you can see in the screenshot.
(I'm sorry I'm not allowed to embed images into my StackOverflow posts yet)
If you could help me answer this question using SQL, that would be great! Thanks
Data
order id
id
size
desired output
1
abcd
2
1
1
abcd
2
1
1
efgh
5
2
1
efgh
5
2
1
efgh
5
2
1
efgh
5
2
2
aa
2
1
2
aa
2
1
2
bb
2
2
2
bb
2
2
SELECT
*,
DENSE_RANK() OVER (PARTITION BY order_item_id ORDER BY id) AS desired_result
FROM
your_table
DENSE_RANK() creates sequences starting from 1 according to the ORDER BY.
Any rows with the same ID will get the same value, and where RANK() would skip values in the event of ties DENSE_RANK() does not.
The PARTITION BY allows new sequences to be created for each different order_item_id.
Related
I want to group records by row numbers.
Like from row 1-3 in group 1 , 4-6 in group 2 , 7-9 in group 3 and so on.
Suppose below is the table structure:
Row NumberDataValue
1 A 10
2 A 5
3 A 1
4 A 33
5 A 2
6 A 127
1 B 1
2 B 0
3 B 7
4 B 7
5 B 5
6 B 8
7 B 1
8 B 0
I want a output like this:
GroupValue
1 10
1 5
1 1
2 33
2 2
2 127
1 1
1 0
1 7
2 7
2 5
2 8
3 1
3 0
I am using Oracle 11G.
I can achieve this using PL/SQL. But I have to use SQL only. As I have to use this query in a reporting tool.
If this is a duplicate question please provide the link of the answered question.
Subtract 1 from the column "RowNumber" and divide by 3.
Then use TRUNC() to get the integer part:
SELECT TRUNC(("RowNumber" - 1) / 3) + 1 "Group",
"Value"
FROM tablename
See the demo.
I would assume the name of the first column is ordering.
You can do:
select
1 + trunc(row_number() over(partition by data order by ordering) - 1) / 3,
value
from t
What you show looks like the output from something like this:
select ceil(rn/3) as grp, value
from your_table
order by rn;
Note that "row number" and "group" are reserved words/phrases which should not be used as column names. I used rn and grp instead.
I think the ceiling function is the simplest way to arrive at what you want. If you want to base it on the RowNumber column:
select ceil( RowNumber / 3.0) as grouping
If you want to calculate it yourself using row_number():
select ceil( row_number() over (order by RowNumber) / 3.0 ) as grouping
i have a table like this
code Quantity
1 5
1 6
2 2
2 1-
3 4
.
.
how can made it like this
code Quantity remain
1 5 5
1 6 11
2 2 2
2 1- 1
3 4 4
.
.
Your query presumes an ordering of the rows. I will assume you have such a column.
Assuming the values are numbers (1- ???), then you can simply use a cumulative sum:
select t.*,
sum(quantity) over (partition by code order by ?) as remaining
from t;
The ? is for the column that specifies the ordering.
You can do a window sum, but you need a column to unambiguously order the records within groups sharing the same code. I assumed that this column is called id.
select t.*, sum(quantity) over(partition by code order by id) remain from mytable t
I have table with data like this
id group order value
-------------------------
1 1 1 23
2 1 2 34
3 2 1 234
4 2 2 77
5 2 3 102
I want to insert into table so I have one row per group, with the value showing a string of comma-separated values orders based on the order.
id group value
----------------
1 1 23,34
2 2 234,77,102
How do I do this? I'm using Postgres 9.3
Postgres supports string_agg():
select row_number() over () as id, "group", string_agg(value, ',' order by "order")
from t
group by "group";
I would look at PostgreSQL's string_agg aggregate function.
I have a table such as this:
Id, ReportId, UserId
1 1 1
2 2 1
3 3 1
4 4 1
5 1 2
6 2 2
7 3 2
8 1 3
9 2 3
10 1 4
My table has thousands of records, above is just an example of the table structure simplified for purpose of understanding the problem.
I'm trying to figure out what at what percentile a user sits based on how many reports he has read.
I've been looking into PERCENTILE_CONT and PERCENTILE_DISC functions, but I fail to understand them properly. https://learn.microsoft.com/en-us/sql/t-sql/functions/percentile-cont-transact-sql
What confuses me most is that what it appears to me is that these functions are trying to find the 50th percentile, not percentile for a specific record.
Maybe I'm just not understanding this correctly. Is there a better way?
EDIT:
To clarify. I want to know at what percentile a specific user (in this case user with id 1) sits based on how many reports they have read. If they read the most reports they would be at a higher percentile, what is that percentile? Lets say there are 100 users exactly, then the person with most reports read would be 1st percentile.
Update #2
One of these should do it:
select
a.UserId,
a.reports_read,
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY a.reports_read) OVER (partition by UserId) AS percentile_d,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY a.reports_read) OVER (partition by UserId) AS percentile_c,
PERCENT_RANK() OVER(ORDER BY a.reports_read ) percent_rank,
CUME_DIST() OVER(ORDER BY a.reports_read ) AS cumulative_distance
from
(select UserId, count(distinct(ReportId)) as reports_read
from #tmp
group by UserId
) a
It gives the following results:
UserId reports_read percentile_d percentile_c percent_rank cumulative_distance
4 1 1 1 0 0.25
3 2 2 2 0.33333 0.5
2 3 3 3 0.66667 0.75
1 6 6 6 1 1
I hope this helps.
I have the table below in an SQL database.
user rating
1 10
1 7
1 6
1 2
2 8
2 3
2 2
2 2
I would like to keep only the best two ratings by user to get:
user rating
1 10
1 7
2 8
2 3
What would be the SQL query to do that? I am not sure how to do it.
It will work
;with cte as
(select user,rating, row_number() over (partition by user order by rating desc) maxval
from yourtable)
select user,rating
from cte
where maxval in (1,2)