not single-group grouping function while using regr_slope - sql

HI I try to run :
select
year,
regr_slope(sum(sale_count),year) as slope,
from products
group by year
It throws "00937. 00000 - "not a single-group group function"" .When i delete year from select clause problem disapears. Shouldn't I be able to select column with which I'm grouping?
Oracle 11.2 sqldeveloper
ty for help !

It's because you're attempting to use a function (REGR_SLOPE) that can be either an aggregate (or analytical) function on the result of another aggregate (SUM) - use:
SELECT x.year,
REGR_SLOPE(sum_sales, x.year) AS slope
FROM (SELECT y.year,
SUM(y.sale_count) AS sum_sales
FROM PRODUCTS y
GROUP BY y.year) x
GROUP BY x.year
Alternative using WITH clause (Oracle 9i+):
WITH sums AS (
SELECT y.year,
SUM(y.sale_count)
FROM PRODUCTS y
GROUP BY y.year)
SELECT x.year,
REGR_SLOPE(sum_sales, x.year) AS slope
FROM sums x
GROUP BY x.year

Did you try it like this?
select
a.year
, regr_slope(a.sale_count,a.year) as slope,
from (SELECT year
, sum(sale_count) sale_count
FROM products
GROUP BY year) a

Related

SQL aggregated subquery - Athena

Using AWS Athena I want to get total recovered per day by getting total recovered amount / total advances
here is code:
SELECT a.advance_date
,sum(a.advance_amount) as "advance_amount"
,sum(a.advance_fee) as "advance_fee"
,(SELECT
sum(credit_recovered+fee_recovered) / (a.advance_amount+a.advance_fee)
FROM ncmxmy.ageing_recovery_raw_parquet
WHERE advance_date = a.advance_date
AND date(recovery_date) <= DATE_ADD('day', 0, a.advance_date)
) as "day_0"
FROM ageing_summary_advance_parquet a
GROUP BY a.advance_date
ORDER BY a.advance_date
I am getting an error
"("sum"((credit_recovered + fee_recovered)) / (a.advance_amount + a.advance_fee))' must be an aggregate expression or appear in GROUP BY clause"
Your division gives the error because the denominator tries to use individual columns from the ageing_summary_advance_parquet table. In my perception of the query, you need to divide by the grouped sum of advance_amount and advance_fee columns. In that case, we can merge two grouped sets of data by advance_date into the division. Please let me know if this query helps:
WITH cte1 (sum_adv_date, advance_date) as
(SELECT
sum(credit_recovered+fee_recovered) as sum_adv_date, advance_date
FROM ncmxmy.ageing_recovery_raw_parquet
WHERE date(recovery_date) <= DATE_ADD('day', 0, advance_date)
GROUP BY advance_date
),
cte2 (advance_date, advance_amount, advance_fee) as
(SELECT
a.advance_date
,sum(a.advance_amount) as "advance_amount"
,sum(a.advance_fee) as "advance_fee"
FROM ageing_summary_advance_parquet a
GROUP BY a.advance_date
)
SELECT cte2.advance_amount, cte2.advance_fee,
(cte1.sum_adv_date/(cte2.advance_amount+cte2.advance_fee)) as "day_0"
FROM cte1 inner join cte2 on cte1.advance_date = cte2.advance_date
ORDER BY cte1.advance_date

Calculate percentage of SQL Group BY

The following SQL statement:
SELECT FTR, COUNT(FTR)
FROM football_data
WHERE Matchday >= '2019-01-18'
GROUP BY FTR
Returns the following result:
Now I'm trying to get a percentage for each of those COUNT(FTR)'s.
So the sum of those 3 numbers is 153. Now I would like to get the percentage of them
You can use window functions, if I understand correctly:
SELECT FTR, COUNT(*),
COUNT(*) * 1.0 / SUM(COUNT(*)) OVER () as ratio
FROM football_data
WHERE Matchday >= '2019-01-18'
GROUP BY FTR;

Problem to fix a question with WindowFunction

For school, I have to answer the following question, using a window function.
For each year, for each month, for each product category, indicate the percentage of that month's turnover that was from the annual turnover of that category.
I tried to use the window function but it didnt work. Because i dont know how to use the over (partition by) function
select
catcode,
year(besteldatum) as jaar,
month(besteldatum) as maand,
sum(regelomzet) as omzet,
sum(regelomzet) / (
select sum(regelomzet)
from ##joinall t2
where t2.catcode = t1.catcode
and year(t2.besteldatum) = year(t1.besteldatum)
) * 100 as perc
from ##joinall t1
group by catcode, year(besteldatum), month(besteldatum)
order by catcode, year(besteldatum), month(besteldatum)
With the window functions there's a thing to realize about them.
They get processed after the GROUP BY.
Hence, it's possible to sum over a sum.
And the PARTITION BY in an OVER is kinda similar to GROUP BY.
SELECT
catcode,
year(besteldatum) as jaar,
month(besteldatum) as maand,
sum(regelomzet) as omzet,
cast(
(sum(regelomzet) /
SUM(sum(regelomzet)) OVER (PARTITION BY catcode, year(besteldatum))) * 100
as decimal(5,2)) as perc
FROM bestellingen t
GROUP BY catcode, year(besteldatum), month(besteldatum)
ORDER BY 1, 2, 3;

Date field not contained in either an aggregate function or the GROUP BY clause

I am trying to calculate "Month to date" using three joined tables. It always gives me error "not contained in either an aggregate function or the GROUP BY clause" The date field is S.BUS_DAT
I tried many things but always get same error. Any advise
Here is the code I use
SELECT
-- Select from IM_IN
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
--Select from IM_ITEM
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
count (S.BUS_DAT) AS BUS_DAYS,
**sum (QTY_SOLD) OVER (PARTITION BY Month (S.BUS_DAT))as **MTD****
FROM
dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M
ON
N.ITEM_NO = M.ITEM_NO
INNER JOIN
dbo.PS_TKT_HIST_LIN S
ON
N.ITEM_NO = S.ITEM_NO
Group by
M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST
Order by M.ITEM_NO
try to include Month(S.BUS_DAT) into group by as well:
SELECT
M.ITEM_NO,
M.DESCR,
N.QTY_ON_HND,
M.PRC_1,
N.LST_COST,
N.LST_RECV_DAT,
M.CATEG_COD,
M.ATTR_COD_1,
M.ITEM_VEND_NO,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.LST_COST,
COUNT(S.BUS_DAT) AS BUS_DAYS,
SUM(QTY_SOLD) OVER(PARTITION BY MONTH(S.BUS_DAT)) AS MTD
FROM dbo.IM_INV N
INNER JOIN dbo.IM_ITEM M ON N.ITEM_NO = M.ITEM_NO
INNER JOIN dbo.PS_TKT_HIST_LIN S ON N.ITEM_NO = S.ITEM_NO
GROUP BY M.ITEM_NO,
M.DESCR,
M.ITEM_VEND_NO,
M.CATEG_COD,
M.ATTR_COD_1,
N.QTY_ON_HND,
N.LST_COST,
N.LST_RECV_DAT,
N.LST_SAL_DAT,
M.ALT_1_UNIT,
M.ALT_1_NUMER,
M.PRC_1,
M.LST_COST,
MONTH(S.BUS_DAT)
ORDER BY M.ITEM_NO;
I believe you want:
sum(sum(QTY_SOLD)) OVER (PARTITION BY Month(S.BUS_DAT)) as MTD
Note: You will still need month(s.bus_dat) in the group by clause.
If you only want the sum for the current month, then you don't want a window function, just conditional aggregation:
sum(case when year(s.bus_dat) = year(getdate()) and month(s.bus_dat) = month(getdate())
then qty_sold
end) as mtd

SQL Grouping Issues

I'm attempting to write a query that will return any customer that has multiple work orders with these work orders falling on different days of the week. Every work order for each customer should be falling on the same day of the week so I want to know where this is not the case so I can fix it.
The name of the table is Core.WorkOrder, and it contains a column called CustomerId that specifies which customer each work order belongs to. There is a column called TimeWindowStart that can be used to see which day each work order falls on (I'm using DATENAME(weekday, TimeWindowStart) to do so).
Any ideas how to write this query? I'm stuck here.
Thanks!
Select ...
From WorkOrder As W
Where Exists (
Select 1
From WorkOrder As W1
And W1.CustomerId = W.CustomerId
And DatePart( dw, W1.TimeWindowStart ) <> DatePart( dw, W.TimeWindowStart )
)
SELECT *
FROM (
SELECT *,
COUNT(dp) OVER (PARTITION BY CustomerID) AS cnt
FROM (
SELECT DISTINCT CustomerID, DATEPART(dw, TimeWindowStart) AS dp
FROM workOrder
) q
) q
WHERE cnt >= 2
SELECT CustomerId,
MIN(DATENAME(weekday, TimeWindowStart)),
MAX(DATENAME(weekday, TimeWindowStart))
FROM Core.WorkOrder
GROUP BY CustomerId
HAVING MIN(DATENAME(weekday, TimeWindowStart)) != MAX(DATENAME(weekday, TimeWindowStart))