How to split a group by query? [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
I have a table like this:
Id 1
Id 2
Amount
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
001
AAA
10
If I do a select query like
SELECT id1,id2,sum(amount),count(*) from table group by id1,id2;
I get the answer like;
001 |AAA |100 |10
What I want to do is split this into two aggregates, so that the first 8 rows will have one aggregate sum and the next 2 should have the sum of next two rows [8 is the cut off].
For example, the answer should be like:
001 |AAA |80 |8
001 |AAA |20 |2
Is it possible to achieve this?
As mentioned in comments, the order of 8 rows+2 rows doesn't matter just that the records in both batches be mutually exclusive. Thanks #SadlyFullStack for the answer!

Since order doesn't matter, we can use ceil and row_number with a null order clause in a CTE to flag every 8 rows with a number. Then, we have another query to aggregate those based on the group number we created:
with grouped as
(
select tbl.*
, ceil(row_number() over (order by null) / 8) grp_num
from tbl
)
select id1
, id2
, sum(amount)
, count(*)
from grouped
group by id1, id2, grp_num

Related

How can I count number of appearance of a value and make it into a new column when querying? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a table like this
ProductID | SalesOrderNumber
1 | SO0001
2 | SO0002
3 | SO0001
4 | SO0001
5 | SO0002
I want to query the table into this
ProductID | SalesOrderNumber | SalesOrderLineNumber
1 | SO0001 | 1
2 | SO0002 | 1
3 | SO0001 | 2
4 | SO0001 | 3
5 | SO0002 | 2
Basically, the SalesOrderLineNumber will count the number of time SalesOrderNumber appear. Everytime a same value of SalesOrderNumber show up, SalesOrderLineNumber increase.
How can I do it?
You should use:
SELECT ProductID,
SalesOrderNumber,
ROW_NUMBER() OVER (PARTITION BY SalesOrderNumber ORDER BY ProductId) as SalesOrderLineNumber
FROM yourTable;
The difference between this and the other answer is the use of ProductId in the ORDER BY clause. You seem to want the line numbers ordered by product id, so this seems to capture the intention.
More importantly: If the order has no duplicate products, then this always produces the same results -- that is, the results are stable. If you repeat the partitioning key, then you could get different results each time you run the query.
You can use a window function, ROW_NUMBER(), for this:
SELECT
ProductID,
SalesOrderNumber,
ROW_NUMBER() OVER (PARTITION BY SalesOrderNumber ORDER BY SalesOrderNumber) as SalesOrderLineNumber
FROM yourTable
The ROW_NUMBER() will count the number of times SalesOrderNumber occurs, as we partition by that.

How do I output rating of teams? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have 2 tables: team(team_id, name), performance(team_id, stage, place, date). Teams should earn points: for 1st place - 10 points, for 2nd 5, for 3rd - 3 points and 1 point for 4-7 places. I need to output the rating of teams.
I think it should be like:
SELECT team.name, CASE place
WHEN 1 points + 10
WHEN 2 points + 5
...
Expected reasult:
|---------------------|------------------|
| team.name | Points |
|---------------------|------------------|
| Rockers | 34 |
|---------------------|------------------|
| Batmans | 23 |
|---------------------|------------------|
| ... | ... |
|---------------------|------------------|
First aggregate inside the table performance to calculate the total points of each team with conditional aggregation and then join the table team to the results and rank the teams with RANK() or maybe DENSE_RANK() analytical functions:
select t.team_id, t.name,
coalesce(p.points, 0) points,
rank() over (order by coalesce(p.points, 0) desc) rnk
from team t left join (
select team_id,
sum(
case
when place = 1 then 10
when place = 2 then 5
when place = 3 then 3
when place <= 7 then 1
else 0
end
) points
from performance
group by team_id
) p on p.team_id = t.team_id

How to remove duplicate rows in postgresql? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I would like to remove duplicate entries in Postgresql.
There is no unique constraint, but I would like to consider all columns together to consider a row as a duplicate.
So we have a table containing following rows :
id | name | age | started_date |Score |
-----|----------|---------------|---------------|------|
1 | tom | 15 | 01/06/2022 |5 |
2 | tom | 15 | 01/06/2022 |5 |
3 | henry | 10 | 01/06/2022 |4 |
4 | john | 11 | 01/06/2022 |6 |
...
I would like to consider all columns together to identify the duplicate rows.
How to achieve this in Postgresql ?
PostgreSQL assigns a ctid pseudo-column to identify the physical location of each row. You could use that to identify different rows with the same values:
-- Create the table
CREATE TABLE my_table (num1 NUMERIC, num2 NUMERIC);
-- Create duplicate data
INSERT INTO my_table VALUES (1, 2);
INSERT INTO my_table VALUES (1, 2);
-- Remove duplicates
DELETE FROM my_table
WHERE ctid IN (SELECT ctid
FROM (SELECT ctid,
ROW_NUMBER() OVER (
PARTITION BY num1, num2) AS rn
FROM my_table) t
WHERE rn > 1);
DB Fiddle
Let say your table has 2 columns, you can identify duplicates using.
Post this :-
1) Insert this result into a temp table
2) Drop data from Main table
3) Insert data from temp table into main table
4) Drop temp table.
select col1, col2, count(*) as cnt
from table1
group by col1, col2
having cnt > 1

sql query get Data on pre conditions [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
i need fruit list which price greater than in tableA for each fruit.
ID | fruit | Price
----------------------------
1 | apple | 10
2 | banana| 7
3 | grapes| 6
then i have daily table like below
ID | fruit | Price
----------------------------
1 | apple | 9
2 | banana| 5
3 | grapes| 9
4 | mango | 15
in this condition i get only grapes
I think you can just join the daily and tableA tables on the fruit's ID, and then compare prices.
SELECT t1.*
FROM daily t1
INNER JOIN tableA t2
ON t1.ID = t2.ID
WHERE t1.price > t2.price
Note that we join on the ID rather than the fruit name, since in theory names may not be completely unique across a very large table of fruits.
just join by ID and add your additional condition (price in tableA is greater than price in dailyTable).
you don't need to join by column fruit - but if so, it won't change your resultset.
SELECT TableA.*, dailyTable.Price
FROM TableA
INNER JOIN dailyTable
ON TableA.ID = dailyTable.ID
AND TableA.Price > dailyTable.Price
the column fruit is redundant data. so you shouldn't store it in the daily table.

Add counter field in select result in Access Query [duplicate]

This question already has an answer here:
Access query producing results like ROW_NUMBER() in T-SQL
(1 answer)
Closed 8 years ago.
I have a table with some field.
name, stud_id
ali | 100
has | 230
mah | 300
I want to get some of record and show a row field beside of record.
1 | ali | 100
2 | has | 230
3 | mah | 300
How I can do it.
Thanks.
Select (select count(*) from Table1 A where A.stud_id>=B.stud_id) as RowNo, B.*
from Table1 as B
order by A.stud_id
MS-ACCESS does not have rownum function, so this might help you.
But your ID need to be sortable and unique.