Caluculating sum of activity - sql

I have a table which is with following kind of information
activity cost order date other information
10 1 100 --
20 2 100
10 1 100
30 4 100
40 4 100
20 2 100
40 4 100
20 2 100
10 1 101
10 1 101
20 1 101
My requirement is to get sum of all activities over a work order
ex: for order 100
1+2+4+4=11
1(for activity 10)
2(for activity 20)
4 (for activity 30) etc.
i tried with group by, its taking lot time for calculation. There are 1lakh plus records in warehouse. is there any possibility in efficient way.
SELECT SUM(MIN(cost))
FROM COST_WAREHOUSE a
WHERE order = 100
GROUP BY (order, ACTIVITY)

You can use the following query to get the sum of cost for distinct tuples of (activity, order, cost)
SELECT SUM(COST)
FROM
(SELECT DISTINCT activity, order, cost
FROM COST_WAREHOUSE WHERE order = 100) AS A

Related

From Quarter-to-date data to daily values on bigquery

I have a bq table that recieves data quarter to date per id
id
value
date
1
200
02/11/2022
2
70
02/11/2022
3
120
02/11/2022
1
150
01/11/2022
2
50
01/11/2022
3
100
01/11/2022
So each id got the cumulative data of the quarter
I need to create a view that takes each day's value minus the day's before per id
for id 1 (02/11 value minus 01/11 value, ...etc)
so the output should be like this
id
value
date
1
50
02/11/2022
2
20
02/11/2022
3
20
02/11/2022
1
150
01/11/2022
2
50
01/11/2022
3
100
01/11/2022
any help is really appreciated
you might consider below query.
SELECT ID, date,
value - LEAD(value, 1, 0) OVER (
PARTITION BY id ORDER BY UNIX_DATE(PARSE_DATE('%d/%m/%Y', date)) DESC
) AS new_value
FROM sample_data;
Query results

SQL - Counting over several groups

I have a list of transactions where the ID's are repeated and I have the quantity of items being bought. I need to count the number of times that a particular number of items were purchased at once.
Row
ItmNBR
TQTY
1
123
5
2
123
5
3
123
5
3
456
25
4
456
19
I need to produce an out put like this...
ItmNBR
QTY
Occurance
123
5
3
123
19
1
123
25
1
I can get the first two columns of my result but when I attempt to counting over a partition I end up counting getting repeating numbers since I'm only looking up 9 items I just count the number of rows in which the Cnt is the same.
TOT_IVO_ITM_QTY
Count(*) OVER (PARTITION BY QTY) AS CNT
FROM dataset
WHERE YEAR(bus_dt) = 2021
AND ITM_NBR IN (12639,12940,12949,12955,13485,13666,43950,631343,1103731)
AND QTY BETWEEN 5 AND 25
ORDER BY ITM_NBR
,QTY
GROUP BY ITM_NBR, TOT_IVO_ITM_QTY```
I think you just want group by:
select ItmNBR, QTY, count(*)
from t
group by ItmNBR, QTY
order by count(*) desc;
This assumes that you want the count by item and quantity, which seems to be the gist of the question.

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);

Assign value to a column based on values of other columns in the same table

I have a table with columns Date and Order. I want to add a column named Batch to this table which will be filled as follows: For each Date, we start from the first Order, and group each two orders in one batch.
It means that for records with Date = 1 in this example (the first 4 records), the first two records (Order= 10 and Order=30) will have batch number: Batch = 1, the next two records (Order = 80 and Order = 110) will have Batch = 2, and so on.
If at the end the number of remaining record(s) is less than the batch size (2 in this example),
the remained order(s) will have a separate Batch number, as in the example below, number of records with Date=2 is odd, so the last record (5th records) will have Batch = 3.
Date Order
-----------
1 10
1 30
1 80
1 110
2 20
2 30
2 50
2 70
2 120
3 90
Date Order Batch
------------------
1 10 1
1 30 1
1 80 2
1 110 2
2 20 1
2 30 1
2 50 2
2 70 2
2 120 3
3 90 1
Use the analytic function row_number to get row numbers 1,2,3,... within each date. Then add one and divide by two:
select
dateid,
orderid,
trunc((row_number() over (partition by dateid order by orderid) +1 ) / 2) as batch
from mytable;