Summing values based on values in other column (Variable) - sql

I would like to sum all items within the query based on their ITEM, keep in mind this query is a daily report that will pick up different ITEM's depending on which items were purchased that day. Therefore, a basic CASE wont work.
For example:
ITEM_TABLE: expected result
Item Type Amount SUM
----------------------------------
SCARF 10 10
T-Shirt 20 45
T-Shirt 25 45
Current Query:
select SUM(AMOUNT)
from EDSREP.V_COGNOS_WSSTOR_SETTLE_RECON a
having CCY_CODE = a.CCY_CODE
Nothing is showing up, please help.

You can use window functions:
select
item_type,
amount,
sum(amount) over(partition by item_type) sum_amount
from item_table

Related

Group certain rows by a value range

I am trying to group a certain records by its price range. Lets say Customer A bought Product B multiple Times as shown below figure, I want to group them together. The Below customer bought products at different price points like 800,810,830,850 etc. I want to compare each price point against others price points in the tables and see if they can grouped together.
Lets say there are ten price points
800,800,850,820,830,1200,1220,1200,1250,1230.
I want to group numbers which are in 10% of its range. The first 5 numbers 800,800,850,820,830 are in one group and the other numbers are in a different group. How can I achieve this SQL Server?
If I understand correctly, you want one group of:
min + 0.1 * (max - min)
for each customer as a group. Then you want the rest in another group. You can use window functions and arithmetic for this:
select t.*,
(case when price <= 0.1 * max(price) over (partition by customer) + 0.9 * min(price) over (partition by customer)
then 1 else 2
end) as the_group
from t;

How to join rows from the same table with different dates

I am only a beginner in SQL and I am encountering the following problem:
I have a table with a list of SKU orders where each row displays the SKU, DELIVERY DATE, AND ORDER QUANTITY. I want to somehow rearrange the table in a way that the rows contain not only the delivery date for that given quantity, but also the following delivery date that occured in the future.
The table currently looks like that:
SKU/ DELIVERY_DATE/ QUANTITY_ORDERED
1.SKUx 14/3/2020 200
2.SKUx 19/3/2020 400
3.SKUx 27/3/2020 550
What I want to achieve is this:
SKU/ DELIVERY_DATE/ **NEXT_DELIVERY_DATE**/ QUANTITY_ORDERED <br/>
1.SKUx 14/3/2020 **19/3/2020** 200
2.SKUx 19/3/2020 **27/3/2020** 400
3.SKUx 27/3/2020 **NULL** 550
Keep in mind, as shown above, that the days between two deliveries vary (5 days between 14/3-19/3 and 8 days between 27/3-19/3) and therefore cannot pick an absolute value to make the column reappear twice e.g
SELECT SKU, DELIVERY_DATE,
DELIVERY_DATE + 5 AS NEXT_DELIVERY_DATE,
QUANTITY_ORDERED
FROM TABLE1
Any help is much appreciated!
Use lead():
select t1.*,
lead(delivery_date) over (partition by sku order by delivery_date) as next_delivery_date
from table1 t1

osclass Counting number of Sales of specifed id products

I have this table item_log:
fk_i_item_id product amount currency status
$sales = $conn->osc_dbFetchResult("SELECT COUNT(status) FROM %st_item_log WHERE fk_i_item_id = '%s' AND status = 'COMPLETED'", DB_TABLE_PREFIX,osc_logged_user_id());
echo $sales['COUNT(status)']
I want to count total number of sales of an product in the same echo.
ex
***********************************************************
fk_i_item_id product amount currency status
***********************************************************
20 Book 1 10 USD COMPLETED
21 Book 2 12 USD COMPLETED
20 Book 1 10 USD COMPLETED
23 Book 3 11 USD COMPLETED
I want an query to count the number or records.
*******************************************************************
fk_i_item_id product amount currency status Sales
*******************************************************************
20 Book 1 10 USD COMPLETED 2
21 Book 2 12 USD COMPLETED 1
23 Book 3 11 USD COMPLETED 1
You already appear to know how to use aggregate functions such as count(), albeit over the entire table.
It's also possible to use these aggregate functions over groups of rows within the table. For example, to get the number of rows for each item ID, it's a simple matter of:
select item_id,
count(*)
from some_table
group by item_id
So all you really need to do is use group by to specify a finer level of grouping since, without that, it will group over all the selected rows.
With regard to your desired output, it would probably make more sense to sum the amount (so that id 20 has an amount of 20 rather than 10) though this may well be complicated by the fact you appear to allow multiple currencies.
I'm not going to tell you how to fix that other than to state that you may need to convert the amounts to a baseline currency before summing them.
So, as a first cut, I'd be looking at something like:
select fk_i_item_id,
max(product) as product,
sum(amount) as amount,
max(currency) as currency,
max(status) as status,
count(*) as sales
from st_item_log
where status = 'COMPLETED'
group by fk_i_item_id
Note the use of the "dummy" max aggregate function on the fields you're not grouping by. This is to ensure that the rows still group on the item ID even if they have different product descriptions, currencies, or status values (though the last is impossible given the where clause).

Group by two columns is possible?

I have this table:
ID Price Time
0 20,00 20/10/10
1 20,00 20/10/10
2 20,00 12/12/10
3 14,00 23/01/12
4 87,00 30/07/14
4 20,00 30/07/14
I use this syntax sql to get the list of all prices in a way that does not get repeated values:
SELECT * FROM myTable WHERE id in (select min(id) from %# group by Price)
This code return me the values (20,14,87,20)
But in this case I would implement another check, that will not only sort by price but also by date, example: That syntax is getting the list by price, if I find a way to check by date, the code will return me the values (20,20,14,87,20)
He repeats 20 two times but if we see in the table we have three numbers 20 (two with the date 20/10/10 and one with the date 12/12/10) and is exactly what I'm wanting to get!
Somebody could help me?
To group by multiple columns, just put a comma in between the list.
SELECT price FROM myTable group by price, time order by time
The group by looks at all distinct combinations of the listed columns values, and discards duplicates. You can also use aggregate functions like sum or max to pull in additional columns to the results.
The following should work as long as all you need is the price/time combination. If you need to include the ID, things get more complicated:
SELECT `Price` FROM items
GROUP BY `Price`, `Time`
ORDER BY `Time`;
Here's a fiddle with the result in action: http://sqlfiddle.com/#!2/40821/1

sql to calculate daily totals minues the previous day's totals

I have a table that has a date, item, and quantity.
I need a sql query to return the totals per day, but the total is the quantity minus the previous day totals. The quantity accumulates as the month goes on. So the 1st could have 5 the 2nd have 12 and the 3rd has 20.
So the 1st adds 5
2nd adds 7 to make 12
3rd adds 8 to make 20.
I've done something like this in the past, but can not find it or remember. I know i'll need a correlated sub-query.
TIA
--
Edit 1
I'm using Microsoft Access.
Date is a datetime field,
item is a text, and
quantity is number
--
Edit 2
Ok this is what i have
SELECT oos.report_date, oos.tech, oos.total_cpe, oos_2.total_cpe
FROM oos INNER JOIN (
SELECT oos_2.tech, Sum(oos_2.total_cpe) AS total_cpe
FROM oos_2
WHERE (((oos_2.report_date)<#10/10/2010#))
GROUP BY oos_2.tech
) oos_2 ON oos.tech = oos_2.tech;
How do i get the oos.report_date into where i says #10/10/2010#. I thought I could just stick it in there like mysql, but no luck. I'm gonna continue researching.
Sum them by adding one to the date and making the value negative, thus taking yesterday's total from today's:
SELECT report_date, tech, Sum(total_cpe) AS total_cpe
FROM (
SELECT oos.report_date, oos.tech, oos.total_cpe
FROM oos
UNION ALL
SELECT oos.report_date+1, oos.tech, 0-oos.total_cpe
FROM oos
)
WHERE (report_date < #10/10/2010#)
GROUP BY report_date, tech
ORDER BY report_date, tech
Ok, I figured it out.
SELECT o.report_date, o.tech, o.total_cpe,
o.total_cpe - (
SELECT IIf(Sum(oos.total_cpe) is null, 0,Sum(oos.total_cpe)) AS total_cpe
FROM oos
WHERE (((oos.tech)=o.tech) AND ((oos.report_date)<o.report_date))
) AS total
FROM oos o;