I'm trying to convert a raw mysql query to use doctrine.
The table is full of rows of statistics, and my query is checking to see how far from the average the stat gain has deviated from the average increase each day.
The SQL version works exactly how I'd expect it to act. Converting to Doctrine gives me an error.
Here's the original:
SELECT
l.*,
DAY(l.created_at) as day,
MONTH(l.created_at) as month,
YEAR(l.created_at) as year,
(
MAX(l.infamyrenown) -
MIN(l.infamyrenown) -
(
SELECT AVG(infamydifference) as avginf FROM
(
SELECT (
MAX(inf.infamyrenown) -
MIN(inf.infamyrenown)
) as infamydifference
FROM lotro_record inf
GROUP BY DAY(inf.created_at)
) as p1
)
) as infamy_deviance
FROM
lotro_record l
GROUP BY
year,month,day
And here's the broken Doctrine query:
Doctrine_Core::getTable("LotroRecord")
->createQuery("l")
->select("l.*")
->addSelect("DAY(created_at)")
->addSelect("MONTH(created_at)")
->addSelect("YEAR(created_at)")
->addSelect("(
MAX(l.infamyrenown) -
MIN(l.infamyrenown) -
(
select AVG(infamydifference) as avginf FROM (
SELECT (
MAX(inf.infamyrenown) -
MIN(inf.infamyrenown)
) as infamydifference
FROM LotroRecord inf
GROUP BY DAY(inf.created_at)
) as p1
)
) as infamy_deviance")
->where("lotro_character_id = {$this->getId()}")
->groupBy("DAY(created_at)");
Which generates this SQL:
SELECT l.id AS l__id,
l.infamyrenown AS l__infamyrenown,
l.kills AS l__kills,
l.killing_blows AS l__killing_blows,
l.kills_above_rating AS l__kills_above_rating,
l.kills_below_rating AS l__kills_below_rating,
l.deaths AS l__deaths,
l.lotro_character_id AS l__lotro_character_id,
l.created_at AS l__created_at,
l.updated_at AS l__updated_at,
DAY(l.created_at) AS l__0,
MONTH(l.created_at) AS l__1,
YEAR(l.created_at) AS l__2,
( Max(l.infamyrenown) - Min(l.infamyrenown) - (SELECT
Avg(infamydifference) AS avginf
FROM
(SELECT ( Max(l2.infamyrenown) - Min(l2.infamyrenown) ) AS l__0
FROM lotro_record l2
GROUP BY DAY(l2.created_at)) AS p1) ) AS l__3
FROM lotro_record l
WHERE ( l.lotro_character_id = 1 )
GROUP BY DAY(l.created_at)
The error is:
Unknown column 'infamydifference' in 'field list'
Any ideas?
I think it wants you to call it inf.infamydifference instead of just infamydifference in the DQL query you're written:
select AVG(inf.infamydifference) as avginf
Related
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
...
select * from batches join (
select * from (
select *, row_number() over (
partition by batch_id
order by date ASC
) as row_num
from batch_schedule where display = 'Yes'
) as d_schedule
where d_schedule.row_num = 1
)
as f_schedule
on batches.id = f_schedule.batch_id
WHERE (f_schedule.date BETWEEN '2021/03/01' AND '2021/04/30')
This query is working fine in version 5.1 but not working in 5.7
What I am trying to achieve is,
filtering batches based on batch_schedule start dates.
I need to select the 1st row from the right table with condition display = 'Yes' and order by date asc and based on that row value i need to display batches.
I am getting the below error message
select is not valid at this position for this server version expecting '(' with
select * from batches join ( SELECT * from batch_schedule
where display = 'Yes' group by batch_id order by date asc )
as f_schedule on batches.id = f_schedule.batch_id
where(f_schedule.date BETWEEN '2021/03/01' AND '2021/04/30');
I tried this and it works.
I am posting here in case if someone looking for the same thing it will help.
I am trying to pivot this data but I am getting an error of
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near ','.
Highlighting the comma after SUM([Total Count]) but it has to be there, what should I change so my query executes properly?
select *
FROM
(
select a.regionalLocale As [RL],
Count(ID) As [Total Count],
CONVERT(VARCHAR(20), dt.week) AS Week
FROM database14.dataTable a
INNER JOIN calendarDB.masterCalendar dt
ON a.SaleDate = dt.FullDate
WHERE a.SaleDate IS NOT NULL
) src
pivot
(
SUM([Total Count]), [RL]
For Week IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
) piv
You've got a few issues with your query.
One you've got the syntax SUM([Total Count]), [RL] in your PIVOT. You only want to include the column you are aggregating here.
Second, there is no need to use count(id) inside your subquery, let the PIVOT aggregation handle the total. Change your code to:
select [RL],
[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13]
FROM
(
select a.regionalLocale As [RL],
ID,
CONVERT(VARCHAR(20), dt.week) AS Week
FROM database14.dataTable a
INNER JOIN calendarDB.masterCalendar dt
ON a.SaleDate = dt.FullDate
WHERE a.SaleDate IS NOT NULL
) src
pivot
(
COUNT(ID)
For Week IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
) piv
can any one help me to convert the following query into mssql which is working on postgresql now
query is to take the updated datetime of the report in the asc order of the date
select
count(*) as count,
TO_CHAR(RH.updated_datetime,'dd-mm-YYYY') as date,
SUM(
extract (
epoch from (
RH.updated_datetime - PRI.procedure_performed_datetime
)
)
)/count(*) as average_reporting_tat
from
report R,
report_history RH,
study S,
procedure_runtime_information PRI,
priorities PP,
patient P,
procedure PR
where
RH.report_fk=R.pk and RH.pk IN (
select pk from (
select * from report_history where report_fk=r.pk order by revision desc limit 1
) as result
where old_status_fk IN (21, 27)
) AND R.study_fk = S.pk
AND S.procedure_runtime_fk = PRI.pk
AND PRI.procedure_fk = PR.pk
AND S.priority_fk = PP.pk
AND PRI.patient_fk = P.pk
AND RH.updated_datetime >= '2013-05-01'
AND RH.updated_datetime <= '2013-05-12'
group by date
If I read your query properly, your problem is that you need to list everything in the group by clause that is in your column list which is not part of an aggregate. So your group by needs to be:
GROUP BY RH.updated_datetime
If this doesn't fix it, please post the error message you are getting.
Suppose equity has a column called TickerID. I would like to replace the 111's with equity.TickerID. MySQL can't seem to resolve the scope and returns an unknown column when I try that. This SQL statement works but I need to run it for each ticker. Would be nice if I could get a full table.
SELECT Ticker,
IF(tbl_m200.MA200_Count = 200,tbl_m200.MA200,-1) AS MA200,
IF(tbl_m50.MA50_Count = 50,tbl_m50.MA50,-1) AS MA50,
IF(tbl_m20.MA20_Count = 20,tbl_m20.MA20,-1) AS MA20
FROM equity
INNER JOIN
(SELECT TickerID,AVG(Y.Close) AS MA200,COUNT(Y.Close) AS MA200_Count FROM
(
SELECT Close,TickerID FROM equity_pricehistory_daily
WHERE TickerID = 111
ORDER BY Timestamp DESC LIMIT 0,200
) AS Y
) AS tbl_m200
USING(TickerID)
INNER JOIN
(SELECT TickerID,AVG(Y.Close) AS MA50,COUNT(Y.Close) AS MA50_Count FROM
(
SELECT Close,TickerID FROM equity_pricehistory_daily
WHERE TickerID = 111
ORDER BY Timestamp DESC LIMIT 50
) AS Y
) AS tbl_m50
USING(TickerID)
INNER JOIN
(SELECT TickerID,AVG(Y.Close) AS MA20,COUNT(Y.Close) AS MA20_Count FROM
(
SELECT Close,TickerID FROM equity_pricehistory_daily
WHERE TickerID = 111
ORDER BY Timestamp DESC LIMIT 0,20
) AS Y
) AS tbl_m20
USING(TickerID)
This seems to be some bug or "feature" of MySQL. Many persons seems to have the same problem with outer tables being out of scope.
Anyway... You could create functions that retrieve the information you want:
DROP FUNCTION IF EXISTS AveragePriceHistory_20;
CREATE FUNCTION AveragePriceHistory_20(MyTickerID INT)
RETURNS DECIMAL(9,2) DETERMINISTIC
RETURN (
SELECT AVG(Y.Close)
FROM (
SELECT Z.Close
FROM equity_pricehistory_daily Z
WHERE Z.TickerID = MyTickerID
ORDER BY Timestamp DESC
LIMIT 20
) Y
HAVING COUNT(*) = 20
);
SELECT
E.TickerID,
E.Ticker,
AveragePriceHistory_20(E.TickerID) AS MA20
FROM equity E;
You would get NULL instead of -1. If this is undesirable, you could wrap the function-call with IFNULL(...,-1).
Another way of solving this, would be to select for the time-frame, instead of using LIMIT.
SELECT
E.TickerID,
E.Ticker,
(
SELECT AVG(Y.Close)
FROM equity_pricehistory_daily Y
WHERE Y.TickerID = E.TickerID
AND Y.Timestamp > ADDDATE(CURRENT_TIMESTAMP, INTERVAL -20 DAY)
) AS MA20
FROM equity E;