SQL: Aggregate by 3 unique column values - sql

Hi I have this table in SQL.
I need to aggregate it to a unique SUBMISSIONNUMBER + ATTACHMENT + BOUND.
For each combination of those I need to aggregate sum up the BOUNDPREMIUM and TECHPREMIUM.
After summing up the BOUNDPREMIUM and TECHPREMIUM, I will then calculate BOUNDTECHNICAL which is BOUNDPREMIUM/TECHPREMIUM.
The expected output looks like this.

We can try the following aggregation query:
SELECT
SUBMISSIONNUMBER,
ATTACHMENT,
BOUND,
SUM(BOUNDPREMIUM) AS BOUNDPREMIUM,
SUM(TECHPREMIUM) AS TECHPREMIUM,
SUM(BOUNDPREMIUM) / SUM(TECHPREMIUM) AS BOUNDTECHNICAL
FROM yourTable
GROUP BY
SUBMISSIONNUMBER,
ATTACHMENT,
BOUND;

Related

Sum of two columns as criteria

I am trying to match product entries by their surface.
My thought was that the below query should be valid.
But it doesn't work, I am receiving:
Unknown column 'surface' in 'where clause'
SELECT SUM(width*height) AS surface FROM products WHERE surface>50
The function sum is not for this use case. With sum you get the sum of all rows. What you are looking for is.
SELECT (width*height) AS surface FROM products WHERE surface>50
This works:
SELECT * FROM products WHERE (width*height)>50

SQL Sum Total with multiple assignments

select dc_id, whse_id, assg_id, START_DTIM,
UNIT_SHIP_CSE*prod_cub as TOTAL_CUBE
from exehoust.aseld
I attached a photo to show how the query currently populates. I want to sum the TOTAL_CUBE for each distinct ASSG_ID. I have tried case where sum and group by but keep failing. Basically want to do a SUM IF for each distinct ASSG_ID
You need to group by the assg_id, but ou need also the define what happens to all the other columns i choose MIN only to give you a hint, you need to choose the function yourself
select MIN(dc_id), MIN(whse_id), assg_id, MIN(START_DTIM),
SUM(UNIT_SHIP_CSE*prod_cub) as TOTAL_CUBE
from exehoust.aseld
GROUP BY assg_id
use select assg_id, sum() over(partition by assg_id order by assg_id) to sum by groupings

Redshift LISTAGG frame clause

I am trying to aggregate strings, but limited to only the preceding rows, not the whole partition. Does anyone know how to do this in Redshift?
What I am trying to achieve is the appended_event_namespace column below.
This is what I've tried so far.
LISTAGG(event_namespace, '/')
WITHIN GROUP (ORDER BY tstamp_true)
OVER (PARTITION BY acct_id) AS appended_event_namespace
This results in the full ApplicationLaunch/CategoryBrowse/NotificationCenter/UserProfile aggregation on every single row instead of what is in the desired screenshot.
The difficulty is in getting it to only append up to the current row since there doesn't seem to be a frame-clause for Redshift's LISTAGG(). Thanks for any ideas that may help.
You can hack this together with another query. Start with your appended_event_namespace as the result of your original LISTAGG
SELECT event_namespace,
SUBSTRING(appended_event_namespace,
1,
POSITION(event_namespace,appended_event_namespace) + LEN(event_namespace) - 1
) as appended_event_namespace_cum
FROM your_table;
Basically, you take your aggregated, ordered string, and then take the first N characters where N is ([where it appears in the aggregated string ]+[its length]), which will cut out everything after that item. This gives you a cumulative namespace.
LISTAGG with frame clause is not supported in RS yet. If you have some columns that you can use for partitioning and ordering you can make a self join (not so performant but would accomplish what you want):
SELECT
t1.id
,t2.tstamp_true
,t1.event_namespace
,LISTAGG(t2.event_namespace,'/') WITHIN GROUP (ORDER BY t2.tstamp_true)
FROM your_table t1
JOIN your_table t2
ON t1.id=t2.id
AND t1.tstamp_true>=t2.tstamp_true
GROUP BY 1,2,3
Alternatively, if you want to avoid self join you can build a JSON with the following structure using LISTAGG:
[{tstamp_true_1,event_namespace_1},{tstamp_true_N,event_namespace_N},...]
and write a Python UDF that takes such JSON for the given group of rows and tstamp_true of the given row and returns the path (the function would need to filter the tstamp_true_N values earlier than the second parameter and concatenate filtered event_namespace_N values for the output)

MS access query aggregation

I am trying to get query like this
SELECT sales.action_date, sales.item_id, items.item_name,
sales.item_quantity, sales.item_price, sales.net
FROM sales INNER JOIN items ON sales.item_id = items.ID
GROUP BY sales.item_id
HAVING (((sales.action_date)=[Forms]![rep_frm]![Text13].[value]));
Every time I try to show data this message show
your query does not include the specified expression ' action date '
as part of aggregate function.
and for all field in the query >>> but i just want the aggregation be for item_id
what i should do?
You don't have any aggregations like SUM in your SELECT statement. I also don't understand why you sales.action_date is in de HAVING clause. This is for aggregated filtering like SUM(sales.item_price) <> 0. It should be possible to put this part in de WHERE-clause, before the GROUP BY instead of the HAVING clause.
This example should work:
SELECT sales.item_id, items.item_name, SUM(sales.item_quantity),
SUM(sales.item_price), SUM(sales.net)
FROM sales INNER JOIN items ON sales.item_id = items.ID
WHERE sales.action_date=[Forms]![rep_frm]![Text13].[value]
GROUP BY sales.item_id, items.item_name;
When you are grouping your data all fields in select query should be either included in group by clause, or some of aggregate functions should be applied to it - otherwise it doesn't makes sanse.
By the way - I far as I can see, you should use WHERE(((sales.action_date)=[Forms]![rep_frm]![Text13].[value])) before group, not having after.
If you want to aggregate by date you have to put the date in the GROUP BY clause
SELECT sales.action_date,
SUM(sales.item_quantity),
SUM(sales.item_quantity * sales.item_price) as Total,
SUM(sales.net)
FROM sales
INNER JOIN items ON sales.item_id = items.ID
WHERE (((sales.action_date)=[Forms]![rep_frm]![Text13].[value]));
GROUP BY sales.action_date
Only the column you want to group by can appear in the GROUP BY clause. Only these columns can appear in the select clause outside of aggregation functions.

Oracle Group by issue

I have the below query. The problem is the last column productdesc is returning two records and the query fails because of distinct. Now i need to add one more column in where clause of the select query so that it returns one record. The issue is that the column i need
to add should not be a part of group by clause.
SELECT product_billing_id,
billing_ele,
SUM(round(summary_net_amt_excl_gst/100)) gross,
(SELECT DISTINCT description
FROM RES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele) productdescr
FROM bil.bill_sum aa
WHERE file_id = 38613 --1=1
AND line_type = 'D'
AND (product_billing_id, billing_ele) IN (SELECT DISTINCT
product_billing_id,
billing_ele
FROM bil.bill_l2 )
AND trans_type_desc <> 'Change'
GROUP BY product_billing_id, billing_ele
I want to modify the select statement to the below way by adding a new filter to the where clause so that it returns one record .
(SELECT DISTINCT description
FROM RRES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele
AND (rate_structure_start_date <= TO_DATE(aa.p_effective_date,'yyyymmdd')
AND rate_structure_end_date > TO_DATE(aa.p_effective_date,'yyyymmdd'))
) productdescr
The aa.p_effective_date should not be a part of GROUP BY clause. How can I do it? Oracle is the Database.
So there are multiple RES.tariff records for a given product_billing_id/billing_ele, differentiated by the start/end dates
You want the description for the record that encompasses the 'p_effective_date' from bil.bill_sum. The kicker is that you can't (or don't want to) include that in the group by. That suggests you've got multiple rows in bil.bill_sum with different effective dates.
The issue is what do you want to happen if you are summarising up those multiple rows with different dates. Which of those dates do you want to use as the one to get the description.
If it doesn't matter, simply use MIN(aa.p_effective_date), or MAX.
Have you looked into the Oracle analytical functions. This is good link Analytical Functions by Example