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 :)
Related
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
I have a MySQL query:
SELECT * FROM product_variants WHERE (bottom_type = '$bottom_type1' OR bottom_type = '$bottom_type2' ) AND (bottom_size = '$bottom_size ' ) AND (product_id != '$product_id1 ' OR product_id != '$product_id2' OR product_id != '$product_id3')
It is not working as it should, its not giving me the results needed.
What is the best way to build it?
Thanks
This is just my guess at what you're after. Example table structure, with data and expected results would help answer your question.
SELECT *
FROM product_variants
WHERE bottom_type IN ('$bottom_type1', '$bottom_type2')
AND bottom_size = '$bottom_size'
AND product_id NOT IN ('$product_id1 ', '$product_id2', '$product_id3')
I'm looking for a way to order my results based on the actual time. In my table yo can see values like:
1,23:45
2,9:45
3,27:43
When I do a query I would like to know how to order them based on their actual 24 hour time.
Ex:
3,3:43
2,9:45
1,23:45
Notice how it changes 27:43 to 3:43, and creates the order.
Where I am using it, in this query:
SELECT *,COALESCE(ADDTIME(s.`departure_time`,SEC_TO_TIME(rt.delay)),s.`departure_time`) as `rt_time` FROM `stop_times` s INNER JOIN `trips` t ON s.`trip_id` = t.`trip_id` INNER JOIN `stops` st ON st.`stop_id` = s.`stop_id` INNER JOIN `routes` r ON r.`route_id` = t.`route_id` LEFT JOIN `rt_trips` rt ON t.`trip_id` = rt.`trip_id` where (s.`stop_id` = 'CB900') and ( ( s.`departure_time` >= '00:50' and s.`departure_time` <= '05:50') OR ( s.`departure_time` >= '24:50' and s.`departure_time` <= '29:50') ) and (s.`pickup_type` = '0') and (t.`service_id` IN ('removed to make it easier')) HAVING (`rt_time` BETWEEN '01:50' and '05:50' ) ) OR ( `rt_time` BETWEEN '25:50' and '29:50' ) ORDER BY `order` ASC
Explanation:
Information is a transit schedule, that may go forward onto the next day which may be a saturday. So, times may become 25:50, where that means 1:50 the next day.
Thanks
Cyrus
Hmmm, if you just want to get a value between 0 and 24 hours, then I would do:
select concat(mod(substring_index(time_column, ':', 1) + 0, 24), ':',
substring_index(time_column, ':', -1)
)
Try this function on the time_column
concat(mod(substr(time_column,1,INSTR(time_column, ':')-1),24)
,substr(time_column,INSTR(time_column, ':'),3)
)
You might need to cast date to string to integer, do the maths, and again cast it to time. But the fiddle version seems to work properly on varchar to integer conversion. Check this
http://sqlfiddle.com/#!9/ff60f9/1
Consider the following query:
SELECT p . *
FROM multiple_picks p
WHERE p.event_id = '3303'
AND p.pick = 'Highlanders'
AND ABS( p.score - '8' ) = (
SELECT MIN( ABS( p2.score -1 ) )
FROM multiple_picks p2
WHERE p2.pick = p.pick
AND p2.event_id = p.event_id )
The query above should return the member(s) who selected the CORRECT TEAM AND the MEMBER(S) who was CLOSEST to Selecting the score. If it is a tie - more than one member should be returned!
When I run the above query on the following table, named multiple_picks:
I get the following result back:
MY PROBLEM
The result returned is incorrect as you can clearly see!
Since the winning team was the Highlanders with a score by 8 (as seen in the query)
The correct result which should have been returned is row2 (the member who picked the Highlanders by 10!)
Any advice as to why I am getting this incorrect result, or what I am doing wrong will be greatly appreciated! Been stuck on this for days now!
SQL FIDDLE
The problem here is that p.score - (const) is compared to p2.score - 1 which is not consistent.
Here's the idea (If I understood the question correctly).
Assume you have variables (or something like that):
T = 'Highlanders'
S = 8
This means you need to find the entry which has p.pick=T and for which the p.score is the closest to S.
Here's what you do (replaced the hardcoded values with the variables above to not distract from the essence of the question) :
SELECT p . *
FROM multiple_picks p
WHERE p.event_id = '3303'
AND p.pick = T
AND ABS(p.score - S) = (
SELECT MIN(ABS(p2.score - S))
FROM multiple_picks p2
WHERE p2.pick = p.pick
AND p2.event_id = p.event_id
)
Updated SQL Fiddle
I'm in the middle of converting an old legacy PHP system to Flask + SQLAlchemy and was wondering how I would construct the following:
I have a model:
class Invoice(db.Model):
paidtodate = db.Column(DECIMAL(10,2))
fullinvoiceamount = db.Column(DECIMAL(10,2))
invoiceamount = db.Column(DECIMAL(10,2))
invoicetype = db.Column(db.String(10))
acis_cost = db.Column(DECIMAL(10,2))
The query I need to run is:
SELECT COUNT(*) AS the_count, sum(if(paidtodate>0,paidtodate,if(invoicetype='CPCN' or invoicetype='CPON' or invoicetype='CBCN' or invoicetype='CBON' or invoicetype='CPUB' or invoicetype='CPGU' or invoicetype='CPSO',invoiceamount,
fullinvoiceamount))) AS amount,
SUM(acis_cost) AS cost, (SUM(if(paidtodate>0,paidtodate,invoiceamount))-SUM(acis_cost)) AS profit FROM tblclientinvoices
Is there an SQLAlchemyish way to construct this query? - I've tried googling for Mysql IF statments with SQlAlchemy but drew blanks.
Many thanks!
Use func(documentation) to generate SQL function expression:
qry = select([
func.count().label("the_count"),
func.sum(func.IF(
Invoice.paidtodate>0,
Invoice.paidtodate,
# #note: I prefer using IN instead of multiple OR statements
func.IF(Invoice.invoicetype.in_(
("CPCN", "CPON", "CBCN", "CBON", "CPUB", "CPGU", "CPSO",)
),
Invoice.invoiceamount,
Invoice.fullinvoiceamount)
)
).label("amount"),
func.sum(Invoice.acis_cost).label("Cost"),
(func.sum(func.IF(
Invoice.paidtodate>0,
Invoice.paidtodate,
Invoice.invoiceamount
))
- func.sum(Invoice.acis_cost)
).label("Profit"),
],
)
rows = session.query(qry).all()
for row in rows:
print row