How to convert below SQL query into sqlalchemy - sqlalchemy

ROUND(SUM(advocate_ptsscored+satisfaction_ptsscored+issueres_ptsscored) OVER (PARTITION BY Agent_EmpId, Supervisor_EmpId, Evaluation_Year, Evaluation_Month ORDER BY Evaluation_Month)/
SUM(advocate_ptsposs +satisfaction_ptsposs +issueres_ptsposs)OVER (PARTITION BY Agent_EmpId, Supervisor_EmpId, Evaluation_Year, Evaluation_Month ORDER BY Evaluation_Month)*100,2) M_Quality_Score

function sqlalchemy.sql.expression.over(element, partition_by=None, order_by=None, range_=None, rows=None)
https://docs.sqlalchemy.org/en/14/core/sqlelement.html?highlight=over#sqlalchemy.sql.expression.over

Related

Doctrine oridinal number with mysql (Error: Expected Literal, got '#')

I need to have an oridinal number from mysql database. I found how emulate of row_num in mysql like this:
SET #row=0;
SELECT * FROM (
SELECT (#row:=#row+1) AS no, id, name FROM `attribute` ORDER BY id
) t WHERE name LIKE "%Jo%"
I begin code with:
$this->getEntityManager()->getConnection()->exec("SET #counter = 0");
and I tried:
$this->result = $this->createQueryBuilder('a')
->select('a')
->where($expr->in('att.ordinal_number', $this->createQueryBuilder('att')->
select('(#counter:=#counter+1) AS ordinal_number')->
from(\App\Entity\Attribute::class, 'att')->
orderBy('att.id')->getDQL()))
and I tried:
$this->result = $this->createQueryBuilder('a')
->select('a')
->addSelect('(SELECT (#counter:=#counter+1) AS oridinal_number, id, '
.' name FROM App:Entity:Atrribute ORDER BY id)')
Above give me:
Error: Expected Literal, got '#'
Anybody know how to emulate row_number in doctrine with mysql?
Thanks in advance.
AFAIK there is no direct way to incorporate these DB variables in DQL or query builder, you will need to execute Native SQL and then use ResultSetMapping class to map the result of query to your entity
SQL
SELECT *
FROM (
SELECT (#row:=#row+1) AS no,
id,
name
FROM `attribute` ,(SELECT #row:=0) t
ORDER BY id
) t WHERE name LIKE "%Jo%"
Resultset Mapping
$rsm = new ResultSetMapping;
$rsm->addEntityResult('Attribute', 'a');
$rsm->addFieldResult('a', 'id', 'id');
$rsm->addFieldResult('a', 'name', 'name');
$rsm->addScalarResult('no', 'no');
$query = $this->_em->createNativeQuery('SELECT *
FROM (
SELECT (#row:=#row+1) AS no,
id,
name
FROM attribute ,(SELECT #row:=0) t
ORDER BY id
) t WHERE name LIKE ?',$rsm);
$query->setParameter(1, '%Jo%');
$users = $query->getResult();

ORA-00979 when using group_by with sqlalchemy

I have a query, which makes a count of the total tasks based on the month of creation, however sqlalchemy is bringing me the following error:
sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) ORA-00979
This is my sqlalchemy query:
tasks_by_month = (
db.session.query(
func.to_char(Task.creation_time, "MM").label("month"),
func.count(Task.id).label("count"),
)
.group_by(func.to_char(Task.creation_time, "MM"))
.order_by(text("month asc"))
.all()
)
This is the query in sqldeveloper:
SELECT
TO_CHAR(TA.CREATION_TIME, 'MM') AS MONTH,
COUNT(TA.ID)
FROM
TASKS TA
GROUP BY
TO_CHAR(TA.CREATION_TIME, 'MM')
ORDER BY
MONTH
I am expecting the following result
Thanks for help
I managed to solve the problem by changing func.to_char(Task.creation_time, "MM").Label ("month") to extract('month', Task.creation_time).label("month").
tasks_by_month = (
db.session.query(
extract('month', Task.creation_time).label("month"),
func.count(Task.id).label("count"),
)
.group_by(extract('month', Task.creation_time))
.order_by(text("month asc"))
.all()
)
Thanks :)

SQL DataBase correction

I have a Device that send event on a SQL data base. The event a log like this:
index|eventNumber|TriggerTime|RecoverTime
The issue I have is if they have a power off/on on the device it create sont unrecover event like this
index|eventNumber|TriggerTime|RecoverTime
1|2|2020-04-03 8:00|2020-04-03 8:10
2|3|2020-04-03 8:00|2020-04-03 8:30
3|3|2020-04-03 8:20|NULL
4|2|2020-04-03 8:21|2020-04-03 8:23
5|3|2020-04-03 8:40|NULL
What I want to do is to copy the triggerTime of the next event with the same eventNumber in the recoverTime. Like this
index|eventNumber|TriggerTime|RecoverTime
1|2|2020-04-03 8:00|2020-04-03 8:10
2|3|2020-04-03 8:00|2020-04-03 8:30
3|3|2020-04-03 8:20|2020-04-03 8:40
4|2|2020-04-03 8:21|2020-04-03 8:23
5|3|2020-04-03 8:40|NULL
What is the best way to do this?
You can use lead():
select el.*,
coalesce(recovertime,
lead(triggertime) over (partition by eventnumber order by triggertime)
) as new_recovertime
from eventlog;
If you need this in an update, you can use join
update eventlog el join
(select el.*,
lead(triggertime) over (partition by eventnumber order by triggertime) as new_recovertime
from eventlog
) el2
on el2.eventnumber = el.eventnumber and
el2.eventtime = el.eventtime
set recovertime = new_recovertime
where recovertime is null and new_recovertime is not null;
the mysql server is 5.7, so it doesn't have the lead fonction. I find a way to do a select to that add a colone with the value to put in the null place, but I don't know how to put it in an update.
(SELECT
event_index, event_log_index, `trigger_time#timestamp`, `recover_time#timestamp`
, (SELECT
`trigger_time#timestamp`
FROM
plc.`test` alfabetInner
WHERE
alfabetInner.`trigger_time#timestamp` > plc.`test`.`trigger_time#timestamp` AND alfabetInner.`event_log_index` = plc.`test`.`event_log_index`
ORDER BY
`trigger_time#timestamp` ASC
LIMIT 0, 1
) AS 'Nexttrigger_time#timestamp'
FROM
plc.`test`
ORDER BY
`trigger_time#timestamp` ASC)

Translate MSSQL query to MySQL 5.7.23

I have a complicated SQL query running on a MSSQL server. I need to change it to make it work also on a MySQL database, however I do not know how to do this. The query is the following and is used to build a complicated Sankey graph in a BI tool
SELECT Id, Delivery_Date, Queue, Step1, Step2, Step3, Step4, Step5, Step6, Step7,
CONVERT(DECIMAL(16,16),RAND((CHECKSUM(NEWID())))*(1 - 0.999999999)+0.999999999) as Counter
FROM
(SELECT t.ID as Id, t.DELIVERY_DATE as Delivery_Date, t.QUEUE as Queue, CONCAT(t.EVENT_NAME,' ', t.EVENT_STATUS, ' ',t .ENDING) as edsda,
'Step' + cast(row_number() over (partition by ID order by ID)
as varchar(10)) ColumnSeq
FROM (SELECT DISTINCT e.[ID] AS ID,
e.[DIALOG_DELIVERY_DATE] AS DELIVERY_DATE,
e.[QUEUE_ID] as QUEUE,
s2.[STEP_NUMBER] AS STEP_NUMBER,
s2.[CURRENT_EVENT] AS EVENT_NAME,
s2.[EVENT_STATUS] as EVENT_STATUS,
e.[DELIVERY_END] AS DELIVERY_END,
CASE WHEN s2.[STEP_NUMBER] = max(s2.[STEP_NUMBER]) over (partition by s2.[ID])
and s2.[EVENT_NUMBER] = min(s2.[EVENT_NUMBER]) over (partition by s2.[ID], s2.[STEP_NUMBER]) THEN e.[DELIVERY_END] ELSE NULL END as ENDING
FROM [dbo].[DELIVERY_STEP_EVENTS] s1,
[dbo].[DELIVERY_STEP_EVENTS] s2,
[dbo].[DELIVERY_EVENTS] e
WHERE s1.[ID] = s2.[ID]
AND e.[ID] = s2.[ID]
AND s1.[EVENT_NAME] = s2.[EVENT_NAME]
AND s1.[STEP_NUMBER] <= s2.[STEP_NUMBER] AS t) AS temp
pivot
(max(edsda)
for ColumnSeq in (Step1,Step2,Step3,Step4, Step5, Step6, Step7)
)
AS Piv
My biggest issue so far has been the RAND((CHECKSUM(NEWID()))) which I do not know how to change to MySQL.
Any help would be greatly appreciated.
My biggest issue so far has been the RAND((CHECKSUM(NEWID()))) which I
do not know how to change to MySQL.
RAND((CHECKSUM(NEWID()))) should behave identical to RAND() function in MySQL. So you could simply replace this:
CONVERT(DECIMAL(16,16),RAND((CHECKSUM(NEWID())))*(1 - 0.999999999)+0.999999999)
With this:
CAST(RAND() * (1 - 0.999999999) + 0.999999999 AS DECIMAL(16, 16))
SQL Server
MySQL

SQL order by string + integers

How can I ORDER BY a string which has ID at the end of the string?
For Example, I want to order these Strings by the numbers at the end (after RSPP):
RSPP891
RSPP896
RSPP897
RSPP898
RSPP899
RSPP900
RSPP901
RSPP902
RSPP903
RSPP904
RSPP730
RSPP731
RSPP1380
RSPP733
RSPP734
I read something about substringing so i tried this query instead, but without any success.
SELECT `RsppTags` FROM Table WHERE ConnectionID = 15202
ORDER BY
SUBSTR(RsppTags FROM 4 FOR LENGTH(RsppTags)-1),
CAST(SUBSTR(RsppTags FROM 1) AS UNSIGNED)
Is it possible to get this data ORDER BY ASC?
SELECT RsppTags FROM Table
WHERE ConnectionID = 15202
ORDER BY CAST(SUBSTR(RsppTags FROM 5) AS UNSIGNED)
By default MYSQL provide ASC ordering.
Try above query.
It will help you.
Try:
ORDER BY CAST(SUBSTR(RsppTags FROM 5) AS UNSIGNED) ASC
Sample SQL Fiddle showing the result
order by SUBSTR(RsppTags, 5) + 0
Try
SELECT `RsppTags` FROM Table WHERE ConnectionID = 15202
ORDER BY CAST(SUBSTR(RsppTags, 5) AS UNSIGNED) ASC;
SELECT `RsppTags`
FROM Table WHERE ConnectionID = 15202
ORDER BY
SUBSTR(RsppTags,1,4),
CAST(SUBSTR(RsppTags,5) AS UNSIGNED);