SQL: Grouping, Count & Average - sql

Trying an SQL question here. I have a SQLite DB (table):
type_id value
1 26
1 24
2 30
3 5
3 15
I want to achieve the following. For each type_id, I would like to know the number of rows (count) with that type_id and the average value (average) of the group. In the example table I would end up with:
type_id count average
1 2 25
2 1 30
3 2 10
Any ideas? Thanks :)

Just GROUP BY type_id and take the COUNT and AVG:
SELECT type_id, COUNT(*) AS count, AVG(value) AS average
FROM test
GROUP BY type_id
Output:
type_id count average
1 2 25
2 1 30
3 2 10
Demo on dbfiddle

Related

sql average on count result

I got a table with the following content:
Order_item
Order-id
item-id
1
45
4
45
4
57
5
68
5
32
6
68
I would like to know how many items are contained in average per order.
I tried that sql query:
select count(item-id), order-id
from order_item
group by order-id
that got me the following result:
Order-id
count
1
1
4
2
5
2
6
1
And now I would divide the 6 items of the count through 4 orders which gets me to my result of average 1,5 items per order.
How would I write a SQL query to get the result 1,5?
Divide count of all rows by distinct IDs and multiply by 1.0 to implicitly cast for numeric division.
select Count(*) / (Count(distinct Order_Id) * 1.0)
from Order_item;

Find count of occurrence of a row

I have a table with duplicate rows and I need to extract these duplicate rows alone. Below is an example of the table I have:
my_table:
ID Offer
1 10
2 10
1 12
1 10
2 20
2 10
What I want next is to count the occurrence of the offer for each ID. i.e, my final result should be:
ID Offer Count
1 10 1
2 10 1
1 12 1
1 10 2
2 20 1
2 10 2
As you can see, the count should increase based on the number of times the offer shows up per ID.
I tried something like:
select id,offer,count(offer) over (partition by id);
But this just gives the total count of that particular offer for that ID and is not the result I am looking for.
Any help is much appreciated!
You could use ROW_NUMBER:
select id,offer,ROW_NUMBER() over (partition by id, offer order by rownum)
from tab

How do I make a query that selects where the SUM equals a fixed value

I've spent that last couple of days searching for a way to make a SQL query that searches the database and returns records where the SUM of the same ID's equal or grater then the value provided.
For this I've been using the W3schools database to test it out in the products table.
More so what I've been trying to do:
SELECT * FROM products
WHERE supplierid=? and SUM(price) > 50
in the "where supplier id" would loop through same suppliers and sum of their price higher than 50 in this case return the records.
In this case it would read supplier ID 1 then add the price of all that supplier 18+19+10=47 now 47 < 50 so it will not print those records at the end. Next supplier ID 2 22+21.35=43.35 and again would not print those records until the sum of price is higher than 50 it will print
I'm working with a DB2 database.
SAMPLE data:
ProductID ProductName SupplierID CategoryID Price
1 Chais 1 1 18
2 Chang 1 1 19
3 Aniseed 1 2 10
4 Chef Anton 2 2 22
5 Chef Anton 2 2 21.35
6 Grandma's 3 2 25
7 Uncle Bob 3 7 30
8 Northwoods 3 2 40
9 Mishi 4 6 97
10 Ikura 4 8 31
11 Queso 5 4 21
12 Queso 5 4 38
13 Konbu 6 8 6
14 Tofu 6 7 23.25
How about:
select * from products where supplierid in (
select supplierid
from products
group by supplierid
having sum(price) > 50
);
The subquery finds out all the supplierid values that match your condition. The main (external) query retrieves all rows that match the list of supplierids.
not tested, but I would expect db2 to have analytic functions and CTEs, so perhaps:
with
basedata as (
select t.*
, sum(t.price) over(partition by t.supplierid) sum_price
from products t
)
select *
from basedata
where supplierid = ?
and sum_price > 50
The analytic function aggregates the price information but does not group the resultset, so you get the rows from your initial result, but restricted to those with an aggregated price value > 50.
The difference to a solution with a subquery is, that the use of the analytic function should be more efficient since it has to read the table only once to produce the result.

Oracle SQL find row crossing limit

I have a table which has four columns as below
ID.
SUB_ID. one ID will have multiple SUB_IDs
Revenue
PAY where values of Pay is always less than or equal to Revenue
select * from Table A order by ID , SUB_ID will have data as below
ID SUB_ID REVENUE PAY
100 1 10 8
100 2 12 9
100 3 9 7
100 4 11 11
101 1 6 5
101 2 4 4
101 3 3 2
101 4 8 7
101 5 4 3
101 6 3 3
I have constant LIMIT value 20 . Now I need to find the SUB_ID which Revenue crosses the LIMIT when doing consecutive SUM using SUB_ID(increasing order) for each ID and then find total Pay ##. In this example
for ID 100 Limit is crossed by SUB ID 2 (10+12) . So total Pay
is 17 (8+9)
for ID 101 Limit is crossed by SUB ID 4
(6+4+3+8) . So total Pay is 18 (5+4+2+7)
Basically I need to find the row which crosses the Limit.
Fiddle: http://sqlfiddle.com/#!4/4f12a/4/0
with sub as
(select x.*,
sum(revenue) over(partition by id order by sub_id) as run_rev,
sum(pay) over(partition by id order by sub_id) as run_pay
from tbl x)
select *
from sub s
where s.run_rev = (select min(x.run_rev)
from sub x
where x.id = s.id
and x.run_rev > 20);

Need help designing a proper sql query

I have this table:
DebitDate | DebitTypeID | DebitPrice | DebitQuantity
----------------------------------------------------
40577 1 50 3
40577 1 100 1
40577 2 75 2
40578 1 50 2
40578 2 150 2
I would like to get with a single query (if that's possible), these details:
date, debit_id, total_sum_of_same_debit, how_many_debits_per_day
so from the example above i would get:
40577, 1, (50*3)+(100*1), 2 (because 40577 has 1 and 2 so total of 2 debits per this day)
40577, 2, (75*2), 2 (because 40577 has 1 and 2 so total of 2 debits per this day)
40578, 1, (50*2), 2 (because 40578 has 1 and 2 so total of 2 debits per this day)
40578, 2, (150*2), 2 (because 40578 has 1 and 2 so total of 2 debits per this day)
So i have this sql query:
SELECT DebitDate, DebitTypeID, SUM(DebitPrice*DebitQuantity) AS TotalSum
FROM DebitsList
GROUP BY DebitDate, DebitTypeID, DebitPrice, DebitQuantity
And now i'm having trouble and i'm not sure where to put the count for the last info i need.
You would need a correlated subquery to get this new column. You also need to drop DebitPrice and DebitQuantity from the GROUP BY clause for it to work.
SELECT DebitDate,
DebitTypeID,
SUM(DebitPrice*DebitQuantity) AS TotalSum,
( select Count(distinct E.DebitTypeID)
from DebitsList E
where E.DebitDate=D.DebitDate) as CountDebits
FROM DebitsList D
GROUP BY DebitDate, DebitTypeID
I think this can help you.
SELECT DebitDate, SUM(DebitPrice*DebitQuantity) AS TotalSum, Count(DebitDate) as DebitDateCount
FROM DebitsList where DebitTypeID = 1
GROUP BY DebitDate