MS access query aggregation - sql

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.

Related

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

Spark throws : "expression is neither present in the group by, nor is it an aggregate function..."

I'm trying to execute this with pyspark:
query = "SELECT *\
FROM transaction\
INNER JOIN factures\
ON transaction.t_num = factures.f_trx\
WHERE transaction.t_num != ''\
GROUP BY transaction.t_num"
result = sqlContext.sql(query)
Spark gives an error :
u"expression transaction.t_aut is neither present in the group by, nor is it an aggregate function. Add to group by or wrap in first() (or first_value) if you don't care which value you get.;
You forgot to add list of columns in group by statement. As you are selecting all columns in select statement.
It's saying that there is column named transaction.t_aut that you have projected in your select statement when you used select * that is not being used in your group by.
Solution is to either replace select * with the columns that are in your group by in your case transaction.t_num or add transaction.t_aut to your group by

SQL Work out average from joined column

I have 3 columns I need to display and I need to join on another column that calculates the AVG from the CLUB_FEE column. My code does not work, it throws a "not a single-group group function" Can someone please help? Here is my SQL:
SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, AVG(C.CLUB_FEE) AVGINCOME
FROM SUBSCRIPTION S, CLUB C
WHERE S.CLUB_ID = C.CLUB_ID;
i Suggest to use Inner join try it also When you include an aggregate function (like avg, sum) in your query, you must group by all columns :
SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, AVG(C.CLUB_FEE) as AVGINCOME
FROM SUBSCRIPTION S INNER JOIN CLUB C
ON S.CLUB_ID = C.CLUB_ID
GROUP BY
S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE ;
Learn to use explicit JOIN syntax. Simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
In your case, you need to remove columns from the SELECT and the GROUP BY. If you want the average fee paid by any member, then you don't need the GROUP BY at all:
SELECT AVG(C.CLUB_FEE) as AVGINCOME
FROM SUBSCRIPTION S JOIN
CLUB C
ON S.CLUB_ID = C.CLUB_ID;
If you want to control the formatting, either use to_char():
SELECT TO_CHAR(AVG(C.CLUB_FEE), '999.99') as AVGINCOME
(check the documentation for other formats).
Or, cast to a decimal:
SELECT CAST(AVG(C.CLUB_FEE) AS DECIMAL(10, 2)) as AVGINCOME
If you need to display the three columns and the average, not just the average alone, you can do something like this:
SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE, A.AVGINCOME
FROM SUBSCRIPTION S INNER JOIN CLUB C
ON S.CLUB_ID = C.CLUB_ID
CROSS JOIN (SELECT AVG(CLUB_FEE) AS AVGINCOME FROM CLUB) A
;
If you need the average rounded to two decimal places, use ROUND(AVG(CLUB_FEE), 2) in the subquery.
A fancier solution, which doesn't require a join (so it doesn't scan the CLUB table twice), uses AVG as an analytic function - but doesn't partition by anything. You still need the PARTITION BY clause (with an empty column list) to indicate it's used as an analytic function, not as an aggregate.
SELECT S.MEMBER_ID, S.CLUB_ID, C.CLUB_FEE,
ROUND(AVG(C.CLUB_FEE) OVER (PARTITION BY NULL)) AS AVGINCOME
FROM SUBSCRIPTION S INNER JOIN CLUB C
ON S.CLUB_ID = C.CLUB_ID
;
Even fancier (although functionally identical) - the keyword OVER is needed to indicate analytic function, but you can also write it as OVER() (no need to even mention PARTITION BY NULL).

Use of the HAVING clause when using muliple sums

I was having a problem getting mulitple sums from multiple tables. Short story, my answer was solved in the "sql sum data from multiple tables" thread on this site. But where it came up short, is that now I'd like to only show sums that are greater than a certain amount. So while I have sub-selects in my select, I think I need to use a HAVING clause to filter the summed amounts that are too low.
Example, using the code specified in the link above (more specifically the answer that the owner has chosen as correct), I would only like to see a query result if SUM(AP2.Value) > 1500. Any thoughts?
If you need to filter on the results of ANY aggregate function, you MUST use a HAVING clause. WHERE is applied at the row level as the DB scans the tables for matching things. HAVING is applied basically immediately before the result set is sent out to the client. At the time WHERE operates, the aggregate function results are not (and cannot) be available, so you have to use a HAVING clause, which is applied after the main query is complete and all aggregate results are available.
So... long story short, yes, you'll need to do
SELECT ...
FROM ...
WHERE ...
HAVING (SUM_AP > 1500)
Note that you can use column aliases in the having clause. In technical terms, having on a query as above works basically exactly the same as wrapping the initial query in another query and applying another WHERE clause on the wrapper:
SELECT *
FROM (
SELECT ...
) AS child
WHERE (SUM_AP > 1500)
You could wrap that query as a subselect and then specify your criteria in the WHERE clause:
SELECT
PROJECT,
SUM_AP,
SUM_INV
FROM (
SELECT
AP1.[PROJECT],
(SELECT SUM(AP2.Value) FROM AP AS AP2 WHERE AP2.PROJECT = AP1.PROJECT) AS SUM_AP,
(SELECT SUM(INV2.Value) FROM INV AS INV2 WHERE INV2.PROJECT = AP1.PROJECT) AS SUM_INV
FROM AP AS AP1
INNER JOIN INV AS INV1 ON
AP1.[PROJECT] = INV1.[PROJECT]
WHERE
AP1.[PROJECT] = 'XXXXX'
GROUP BY
AP1.[PROJECT]
) SQ
WHERE
SQ.SUM_AP > 1500

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