GROUPed or used in an aggregate function error - mysql

I want to Group By CUSTOM_DRIVER in the query because I am getting over 1.3 million results and I just need to view them by Custom Driver for the month by store.
The query is returning me
I want something like this
I've tried using Distinct and Group By but I keep getting the error:
Attribute A.STORE_NUM must be GROUPed or used in an aggregate function
How do I get around this? The code I've been using is:
SELECT *
FROM(
SELECT
SE.STORE_NUM,
DM.MONTH_NAME_445 AS MO_445,
--DM.WEEK_START_DT_MON AS WK_BEGIN_MONDAY,
--SE.METRIC_DATE,
substring(SE.ROLLUP_NAME, 39, 20) as CUSTOM_DRIVER,
SE.DT_IMPORTED,
SE.METRIC_VALUE
FROM DNA_PUBLIC.ADMIN.SCHEDULE_EFFECTIVENESS SE
JOIN DNA_PUBLIC.ADMIN.DAY_MAP DM ON SE.METRIC_DATE = DM.DATE_DT
JOIN (
SELECT DISTINCT
METRIC_DATE,
MAX(DATE(DT_IMPORTED)) AS MAX_DT
FROM DNA_PUBLIC.ADMIN.SCHEDULE_EFFECTIVENESS
GROUP BY 1
) MX ON SE.METRIC_DATE = MX.METRIC_DATE
WHERE METRIC_NAME = 'Coverage Effectiveness'
AND SE.ROLLUP_NAME LIKE 'O%'
AND SE.METRIC_DATE between '07/27/2020' and '11/11/2020'
AND CAST(SE.DT_IMPORTED AS DATE) = MAX_DT
--AND CUSTOM_DRIVER = 'Truck/Truck'
AND SE.INDICATOR_NAME = 'Required'
--and STORE_NUM = 1
) AS A
Order by STORE_NUM

A work around was to select the values and group by the order of the selected variables. Thanks for the all the input!
SELECT
STORE_NUM,
MO_445,
CUSTOM_DRIVER,
SUM(METRIC_VALUE) as Tot_Hrs
FROM(
SELECT
SE.STORE_NUM,
DM.MONTH_NAME_445 AS MO_445,
DM.WEEK_START_DT_MON AS WK_BEGIN_MONDAY,
SE.METRIC_DATE,
substring(SE.ROLLUP_NAME, 39, 20) as CUSTOM_DRIVER,
SE.DT_IMPORTED,
SE.METRIC_VALUE
FROM DNA_PUBLIC.ADMIN.SCHEDULE_EFFECTIVENESS SE
JOIN DNA_PUBLIC.ADMIN.DAY_MAP DM ON SE.METRIC_DATE = DM.DATE_DT
JOIN (
SELECT DISTINCT
METRIC_DATE,
MAX(DATE(DT_IMPORTED)) AS MAX_DT
FROM DNA_PUBLIC.ADMIN.SCHEDULE_EFFECTIVENESS
GROUP BY 1
) MX ON SE.METRIC_DATE = MX.METRIC_DATE
WHERE METRIC_NAME = 'Coverage Effectiveness'
AND SE.ROLLUP_NAME LIKE 'O%'
AND SE.METRIC_DATE between '07/27/2020' and '11/11/2020'
AND CAST(SE.DT_IMPORTED AS DATE) = MAX_DT
--AND CUSTOM_DRIVER = 'Truck/Truck'
AND SE.INDICATOR_NAME = 'Required'
and STORE_NUM = 1
) AS A
group by 1,2,3
Order by STORE_NUM

Related

MYSQL error code: 1054 Unknown column in where clause. Error occurring in Nested SubQueries

I am trying to get through a problem where there are multiple accounts of same scheme on same customer id. On a given txn date I want to retrieve the total Sanctioned Limit and total utilized amount from these accounts. Below is the SQL query I have constructed.
SELECT
cust_id,
tran_date,
rollover_date,
next_rollover,
(
SELECT
acc_num as kcc_ac
FROM
dbzsubvention.acc_disb_amt a
WHERE
(a.tran_date <= AB.tran_date)
AND a.sch_code = 'xxx'
AND a.cust_id = AB.cust_id
ORDER BY
a.tran_date desc
LIMIT
1
) KCC_ACC,
(
SELECT
SUM(kcc_prod)
FROM
(
SELECT
prod_limit as kcc_prod,
acc_num,
s.acc_status
FROM
dbzsubvention.acc_disb_amt a
inner join dbzsubvention.acc_rollover_all_sub_status s using (acc_num)
left join dbzsubvention.acc_close_date c using (acc_num)
WHERE
a.cust_id = AB.cust_id
AND a.tran_date <= AB.tran_date
AND (
ac_close > AB.tran_date || ac_close is null
)
AND a.sch_code = 'xxx'
AND s.acc_status = 'R'
AND s.rollover_date <= AB.tran_date
AND (
AB.tran_date < s.next_rollover || s.next_rollover is null
)
GROUP BY
acc_num
order by
a.tran_date
) t
) kcc_prod,
(
SELECT
sum(disb_amt)
FROM
(
SELECT
disb_amt,
acc_num,
tran_date
FROM
(
SELECT
disb_amt,
a.acc_num,
a.tran_date
FROM
dbzsubvention.acc_disb_amt a
inner join dbzsubvention.acc_rollover_all_sub_status s using (acc_num)
left join dbzsubvention.acc_close_date c using (acc_num)
WHERE
a.tran_date <= AB.tran_date
AND (
c.ac_close > AB.tran_date || c.ac_close is null
)
AND a.sch_code = 'xxx'
AND a.cust_id = AB.cust_id
AND s.acc_status = 'R'
AND s.rollover_date <= AB.tran_date
AND (
AB.tran_date < s.next_rollover || s.next_rollover is null
)
GROUP BY
acc_num,
a.tran_date
order by
a.tran_date desc
) t
GROUP BY
acc_num
) tt
) kcc_disb
FROM
dbzsubvention.acc_disb_amt AB
WHERE
AB.cust_id = 'abcdef'
group by
cust_id,
tran_date
order by
tran_date asc;
This query isn't working. Upon research I have found that correlated subquery works only till 1 level down. However I couldn't get a workaround to this problem.
I have tried searching the solution around this problem but couldn't find the desired one. Using the SUM function at the inner query will not give desired results as
In the second subquery that will sum all the values in column before applying the group by clause.
In third subquery the sorting has to be done first then the grouping and finally the sum.
Therefore I am reaching out to the community for help to suggest a workaround to the issue.
You're correct - external column cannot be transferred through the nesting level immediately.
Try this workaround:
SELECT ... -- outer query
( -- correlated subquery nesting level 1
SELECT ...
( -- correlated subquery nesting level 2
SELECT ...
...
WHERE table0_level1.column0_1 ... -- moved value
)
FROM table1
-- move through nesting level making it a source of current level
CROSS JOIN ( SELECT table0.column0 AS column0_1 ) AS table0_level1
) AS ...,
...
FROM table0
...

Why integer cast is not working with integer group_concat() list?

I'm stuck at the query where I need to concat IDs of the table. And from that group of IDs, I need to fetch that rows in sub query. But when I try to do so, MySQL consider group_concat() as a string. So that condition becomes false.
select count(*)
from rides r
where r.ride_status = 'cancelled'
and r.id IN (group_concat(rides.id))
*************** Original Query Below **************
-- Daily Earnings for 7 days [Final]
select
group_concat(rides.id) as ids,
group_concat(ride_category.name) as rideType,
group_concat(ride_cars.amount + ride_cars.commission) as rideAmount ,
group_concat(ride_types.name) as carType,
count(*) as numberOfRides,
(
select count(*) from rides r where r.ride_status = 'cancelled' and r.id IN (group_concat(rides.id) )
) as cancelledRides,
(
select count(*) from rides r where r.`ride_status` = 'completed' and r.id IN (group_concat(rides.id))
) as completedRides,
group_concat(ride_cars.status) as status,
sum(ride_cars.commission) + sum(ride_cars.amount) as amount,
date_format(from_unixtime(rides.requested_at/1000 + rides.offset*60), '%Y-%m-%d') as requestedDate,
date_format(from_unixtime(rides.requested_at/1000 + rides.offset*60), '%V') as week
from
ride_cars,
rides,
ride_category,
ride_type_cars,
ride_types
where
ride_cars.user_id = 166
AND (rides.ride_status = 'completed' or. rides.ride_status = 'cancelled')
AND ride_cars.ride_id = rides.id
AND (rides.requested_at >= 1559347200000 AND requested_at < 1561852800000)
AND rides.ride_category = ride_category.id
AND ride_cars.car_model_id = ride_type_cars.car_model_id
AND ride_cars.ride_type_id = ride_types.id
group by
requestedDate;
Any solutions will be appreciated.
Try to replace the sub-query
(select count(*) from rides r where r.ride_status = 'cancelled' and r.id IN (group_concat(rides.id) )) as cancelledRides,
with below to count using SUM and CASE, it will make use of the GROUP BY
SUM(CASE WHEN rides.ride_status = 'cancelled' THEN 1 ELSE 0 END) as cancelledRides
and the same for completedRides
And move to using JOIN instead of implicit joins

Getting the sum of column grouped by date

Was wondering if there is a way to get the sum of the stock_case column for items with the same date_of_export ?
Updated with fiddle here and some relevant data:
https://www.db-fiddle.com/f/szC1Ftj3ZGEC24gSYp6ad4/4
The expected output would be this:
This is the query used
SELECT
st.product_code,
st.date_of_export,
st.best_before_date,
st.stock_case,
(
SELECT
SUM(st2.stock_case)
FROM
stock_tracking AS st2
WHERE
st2.product_code IN ('MGN003')
AND MONTH(st2.date_of_export) IN (07)
AND YEAR(st2.date_of_export) IN (2018)
AND st2.stock_case != 0
) AS total
FROM
stock_tracking st
WHERE
product_code IN ('MGN003')
AND MONTH(st.date_of_export) IN (07)
AND YEAR(st.date_of_export) IN (2018)
AND stock_case != 0
and my results
Would like to have a total column like 16, 16, 16, ... , 19, etc
For another case I used a subquery like so
SELECT
d.products_name,
stock_case,
st.date_of_export,
st.best_before_date,
st.product_code,
(SELECT
SUM(st2.stock_case)
FROM
stock_tracking AS st2
WHERE
DATE(st2.date_of_export) = (SELECT
DATE(tmp.last_update)
FROM
(SELECT
date_of_export AS last_update
FROM
stock_tracking
ORDER BY date_of_export DESC
LIMIT 1) AS tmp
WHERE
product_code = 'MGN003')) AS total
FROM
stock_tracking st
LEFT JOIN
products AS p ON p.products_model = st.product_code
LEFT JOIN
products_description AS d ON d.products_id = p.products_id
WHERE
product_code = 'MGN003'
AND d.language_id = 2
AND DATE(st.date_of_export) = (SELECT
DATE(tmp.last_update)
FROM
(SELECT
date_of_export AS last_update
FROM
stock_tracking AS st
ORDER BY date_of_export DESC
LIMIT 1) AS tmp)
with this result:
You can write a subquery to sum(stock_case) by date_of_export, then self join on Date, then you can get your expect result.
SELECT
s.product_name,
s.date_of_export,
s.best_before_date,
s.product_code,
s.stock_case,
t.totle
FROM
stock_tracking s
INNER JOIN
(
SELECT SUM(stock_case) totle,date_of_export dt
FROM stock_tracking
where
product_code = 'MGN003'
AND MONTH(date_of_export) =07
AND YEAR(date_of_export) =2018
AND stock_case != 0
GROUP BY date_of_export
) t on DATE_FORMAT(s.date_of_export, "%d-%m-%Y") = DATE_FORMAT(t.dt, "%d-%m-%Y")
where
s.product_code = 'MGN003'
AND MONTH(s.date_of_export) =07
AND YEAR(s.date_of_export) =2018
AND s.stock_case != 0
sqlfiddle
Without giving you the exact answer: You should think in the direction of:
SELECT SUM(column) FROM table WHERE ... GROUP BY date
or
SELECT SUM(column), DISTINCT date FROM table WHERE ...
So lookup the way GROUP BY and DISTINCT work :-)

Mysql Group by With Condition

The below data shows time schedule having elective/ non-elective subjects of a student. My requirement is to select those rows when both elec and nonelec type has same period so in this case select elec type. Means for a day's schedule elective (type elec) should be given preference when both having same period. And when type elec does not has period like period 5 then select the non-elective one.
My Query
SELECT s.sch_id, s.sch_subtype, sd.sdetail_id, sd.sdetail_period
FROM schedule s
INNER JOIN schedule_detail sd ON s.sch_id = sd.sdetail_schedule
WHERE '2014-04-30'
BETWEEN sch_datefrom
AND sch_dateto
AND
(
(
sch_section =1
AND sch_subtype = 'nonelec'
)
OR
(
sch_subtype = 'elec'
AND 272
IN
(
SELECT edetail_stuid
FROM elective_detail
WHERE edetail_elective = sch_section
)
)
)
AND sch_course =3
AND sch_batch =2
AND sch_termid =2
AND sdetail_day = 'wed'
AND sdetail_period >0
AND CASE WHEN sch_subtype = 'nonelec'
THEN 1 =1
WHEN sch_subtype = 'elec'
THEN sdetail_subject >0
AND sdetail_faculty >0
AND sdetail_room >0
END GROUP BY CASE WHEN sch_subtype = 'elec'
THEN sdetail_period
ELSE 1
END ORDER BY sdetail_period
Output of above query
Required Output
You can try something of this sort :
SELECT sch_id,sch_subtype,sdetail_id,sdetail_period
FROM table
WHERE condition
group by sch_subtype
It would be better if you can post the query which u tried.
Dont really get whats the problem here:
SELECT * FROM schedule s
JOIN schedule_detail sd ON s.sch_id = sd.sdetail_schedule
LEFT JOIN elective_detail ed ON sd.sch_section = ed.edetail_elective
WHERE
(
sd.sch_section =1
AND s.sch_subtype = 'nonelec'
)
OR
(
ed.edetail_stuid = 227
AND sch_subtype = 'elec'
)
GROUP BY sd.sdetail_period
SQL Fiddle: http://sqlfiddle.com/#!2/69d4e/1

Concatenation using a mysql variable

The problem in my query particularly in this piece:
#a:= concat(#a, ',', B.call_account_id) AS paid_account_id
Here is the whole query:
SELECT operator_id, paid_account_ids, SUM( goods_count * price ) AS sales_volume, count(*) AS sales_cnt
FROM (
SELECT B.operator_id, #a:= concat(#a, ',', B.call_account_id) AS paid_account_ids, B.call_time, A.goods_count, A.price, UNIX_TIMESTAMP( A.completion_date ) AS paid_ts
FROM call_module_data B
INNER JOIN ak_accounts A ON ( A.account_id = B.call_account_id AND A.goods_count >=1 )
WHERE B.call_status IN (1,7) AND A.status_id = 5
AND operator_id IN ( $op_ids )
$and_str_accounts
GROUP BY A.account_id
HAVING call_time < (paid_ts + $time_shift)
) AS T
GROUP BY operator_id";
So the expression mentioned above should produce the concatenated string of account ids (e.g 3341,4355,4433...). But I got NULL instead of desired string.
Please help to resolve. Thanks in advance.
Use GROUP_CONCAT() function instead of String concatenation
Change
#a:= concat(#a, ',', B.call_account_id) AS paid_account_id
above string to
GROUP_CONCAT(B.call_account_id) AS paid_account_ids
Final Answer:
SELECT operator_id, GROUP_CONCAT(paid_account_ids) AS paid_account_ids,
SUM(goods_count * price) AS sales_volume, COUNT(*) AS sales_cnt
FROM (SELECT B.operator_id, GROUP_CONCAT(B.call_account_id) AS paid_account_ids,
B.call_time, A.goods_count, A.price,
UNIX_TIMESTAMP(A.completion_date) AS paid_ts
FROM call_module_data B
INNER JOIN ak_accounts A ON A.account_id = B.call_account_id AND A.goods_count >=1
WHERE B.call_status IN (1,7) AND A.status_id = 5 AND operator_id IN ($op_ids)
$and_str_accounts
GROUP BY A.account_id HAVING call_time < (paid_ts + $time_shift)
) AS T
GROUP BY operator_id;