SELECT
t.imei,
t.date,
t.time startTime,
t.ignition,
t.tripStartStop,
(
SELECT
min(time)
from
gps_data
where
time > t.time
and date >= t.date
and imei = '358480088853405'
and tripStartStop = 0
) ' stopTime',
SUBTIME('startTime', 'stopTime') AS diff
from
gps_data t
where
imei = '358480088853405'
and date >= '2020-03-08'
and date <= '2020-03-09'
and tripStartStop = 1
the above query returns startTime and stopTime as alias values but i can't get the difference of these two times
used both SUBTIME and TIMEDIFF
You cannot use aliases like that. The query:
SUBTIME('startTime','stopTime')
treats the startTime and stopTime as strings, hence the 00:00:00.
What you can do is following:
select q.imei, q.date, q.startTime, q.ignition,
q.tripStartStop, q.stopTime, subtime(q.startTime, q.stopTime)
from (
SELECT t.imei
, t.date
, t.time startTime
, t.ignition
, t.tripStartStop
, ( SELECT min(time) from gps_data where time>t.time and date>=t.date and imei='358480088853405' and tripStartStop=0 ) 'stopTime'
from gps_data t
where
imei='358480088853405'
and date between '2020-03-08' and '2020-03-09'
and tripStartStop=1
) as q
You need to select 'starTime' and 'stopTime' using select statement within the Substring. That would solve your problem.
SUBTIME(SELECT(startTime),SELECT(stopTime))
SELECT t.imei
, t.date
, t.time startTime
, t.ignition
, t.tripStartStop
, ( SELECT min(time) from gps_data where time>t.time and date>=t.date and imei='358480088853405' and tripStartStop=0 ) ' stopTime'
, SUBTIME(SELECT(startTime),SELECT(stopTime)) diff
from gps_data t
where imei='358480088853405'
and date>='2020-03-08'
and date<='2020-03-09'
and tripStartStop=1````
Related
Looking at other posts was not working due to my lack of ability .
I am trying to extract a Cohort from the date of installation .
information TABLE
u_status
used : created_at , last_login
u_daily_login
SQL
SET
#targetDate = '2020-07-01';
SELECT
#Datecount := TIMESTAMPDIFF(
DAY,
#targetDate,
DATE_FORMAT(NOW(), '%Y-%m-%d')) -1;
SELECT
dl.df,
COUNT(udl.uMasterId)
FROM
(
SELECT
DATE_FORMAT(
DATE_ADD(
#targetDate,
INTERVAL td.generate_series DAY
),
'%Y-%m-%d'
) AS df
FROM
(
SELECT
0 generate_series
FROM DUAL
WHERE
(#num := 1 -2) * 0
UNION ALL
SELECT
#num := #num +1
FROM
`information_schema`.COLUMNS
WHERE
#num <= #Datecount
) AS td
) AS dl
LEFT JOIN(
SELECT udlt.*
FROM
(
SELECT
*
FROM
u_daily_login
WHERE
DATE >= #targetDate
) AS udlt
INNER JOIN(
/*基準日に登録したユニークユーザー*/ SELECT
*
FROM
(
SELECT
DATE_FORMAT(us.`createdAt`, '%Y-%m-%d') AS cdate,
us.name,
uMasterId
FROM
u_status AS us
WHERE
DATE_FORMAT(us.`createdAt`, '%Y-%m-%d') = #targetDate
) AS noise
GROUP BY
noise.name
) AS uus
ON
uus.uMasterId = udlt.uMasterId
) AS udl
ON
dl.df = udl.date
GROUP BY
dl.df
LIMIT 100;
I got the desired result, As it is now, I'm typing targetDate manually.
ex. #targetDate = 2020-07-02 , "targetDate = 2020-07-03 ...etc
How can I efficiently extract daily cohorts?
I have one SQL queries
with temp as
(
select min(ms_date) as start, max(ms_date) as [end], count(sessionid) 'visitor_count',category,convert(varchar, ms_date , 106) 'ms_date'
from temp_tbltrack where category =#id
group by category,convert(varchar, ms_date , 106)
)
select category,ms_date,CASE WHEN datediff(ss,temp.start,temp.[end]) <>0 THEN datediff(ss,temp.start,temp.[end]) ELSE 45 END 'Timespan',visitor_count from temp
order by convert(datetime,ms_date)
I converted into Mysql
select temp from
(
select min(ms_date) as start, max(ms_date) as `end`, count(sessionid) 'visitor_count',category,date_format (ms_date , 106) 'ms_date'
from temp_tbltrack where category =p_id
group by category,date_format (ms_date , 106)
)
select category,ms_date,CASE WHEN timestampdiff(ss,temp.start,temp.[end]) <>0 THEN timestampdiff(ss,temp.start,temp.[end]) ELSE 45 END 'Timespan',visitor_count from temp
order by convert(ms_date, datetime);
How I convert CTE in Mysql 5.7 version
I don't think a subquery is needed:
select category,
format(ms_date, '%d %b %Y') as ms_date,
(case when max(ms_date) = min(ms_date)
then 45
else timestampdiff(second, min(ms_date), max(ms_date))
end) as timestamp
count(sessionid) as `visitor_count`,
from temp_tbltrack
where category = #id
group by category, format(ms_date, '%d %b %Y')
order by min(ms_date);
you can use subqueries since you can't use cte on your mysql version.
select t1.category
, t1.ms_date
, case when datediff(ss, temp.start, temp.[end]) <> 0
then datediff(ss,temp.start,temp.[end]) else 45 end 'Timespan'
, t1.visitor_count
from
(select min(ms_date) as start, max(ms_date) as [end], count(sessionid) 'visitor_count', category, cast(ms_date as date) 'ms_date'
from temp_tbltrack where category =#id
group by category, cast(ms_date as date)) t1
order by cast(t1.ms_date as datetime)
I want to select last information about client's balance from MySQL's database. I wrote next script:
SELECT *
FROM
(SELECT
contract_balance.cid,
/*contract_balance.yy,
contract_balance.mm,*/
contract_balance.expenses,
contract_balance.revenues,
contract_balance.expenses + contract_balance.revenues AS total,
(CAST(CAST(CONCAT(contract_balance.yy,'-',contract_balance.mm,'-01')AS CHAR) AS DATE)) AS dt
FROM contract_balance
/*WHERE
CAST(CAST(CONCAT(contract_balance.yy,'-',contract_balance.mm,'-01')AS CHAR) AS DATE) < '2013-11-01'
LIMIT 100*/
) AS tmp
WHERE tmp.dt = (
SELECT MAX(b.dt)
FROM tmp AS b
WHERE tmp.cid = b.cid
)
But server return:
Table 'clientsdatabase.tmp' doesn't exist
How to change this code for get required data?
Try this one in your subquery you are trying to get the MAX of (CAST(CAST(CONCAT(contract_balance.yy,'-',contract_balance.mm,'-01')AS CHAR) AS DATE)) AS dt but in subquery your aliased table tmp doesn't exist so the simplest way you can do is to calculate the MAX of dt and use GROUP BY contract_balance.cid contractor id ,i guess it will fullfill your needs
SELECT
contract_balance.cid,
contract_balance.expenses,
contract_balance.revenues,
contract_balance.expenses + contract_balance.revenues AS total,
MAX((CAST(CAST(CONCAT(contract_balance.yy,'-',contract_balance.mm,'-01')AS CHAR) AS DATE))) AS dt
FROM contract_balance
GROUP BY contract_balance.cid
Try this:
SELECT *
FROM (SELECT cb.cid, cb.expenses, cb.revenues, cb.expenses + cb.revenues AS total,
(CAST(CAST(CONCAT(cb.yy,'-',cb.mm,'-01')AS CHAR) AS DATE)) AS dt
FROM contract_balance cb ORDER BY dt DESC
) AS A
GROUP BY A.cid
This is an extract sql that gets days
AND S.Date IN
(
SELECT Date
FROM
(
SELECT Date,
ROW_NUMBER() OVER (ORDER BY Date DESC )-1 Day
FROM CALENDAR_DIM
WHERE TYPE = 'ABC'
)
WHERE BUS_DAY BETWEEN 0 AND 2
)
I want to run this code twice in two parts of my sql. How can i do that without pasting the same code. Also .. how could i rewrite the above code?. I am having some issues with performance.
Solution 1 : use a WITH statement
WITH dateQuery AS (
SELECT Date
FROM
(
SELECT Date,
ROW_NUMBER() OVER (ORDER BY Date DESC )-1 BUS_DAY
FROM CALENDAR_DIM
WHERE TYPE = 'ABC'
)
WHERE BUS_DAY BETWEEN 0 AND 2)
SELECT xxx
FROM yyy
WHERE zzz
AND s.Date IN (SELECT Date FROM dateQuery)
The only part to repeat will then be
SELECT Date FROM dateQuery
Solution 2 : create a View
CREATE OR REPLACE VIEW V_DATE_QUERY AS
( SELECT Date
FROM
(
SELECT Date,
ROW_NUMBER() OVER (ORDER BY Date DESC )-1 BUS_DAY
FROM CALENDAR_DIM
WHERE TYPE = 'ABC'
)
WHERE BUS_DAY BETWEEN 0 AND 2)
and use it the same way
AND s.Date IN (Select Date FROM V_DATE_QUERY);
You would make this a view in your database like so:
CREATE VIEW view_date
AS
SELECT Date,
ROW_NUMBER() OVER (ORDER BY Date DESC )-1 Day
FROM CALENDAR_DIM
WHERE TYPE = 'ABC'
Now you can use:
AND S.Date IN
(
SELECT Date
FROM view_date
WHERE BUS_DAY BETWEEN 0 AND 2
)
I have a query that I have simplified and written below.
How do I display the time difference of 2 fields that were calculated as 2 separate inline select statements?
SELECT x.name ,
( SELECT data.ts
FROM data
WHERE prim_key = x.prim_key and roll_no ='1'
) **starttime** ,
( SELECT data.ts
FROM woman_data
WHERE prim_key = x.prim_key and roll_no ='10'
) **endtime**
, **TIME_TO_SEC( TIMEDIFF( endtime , starttime)** as timediff // This line does not work.It cannot recognize endtime ans starttime
FROM data x
INNER JOIN y
ON x.prim_key = y.prim_key
ORDER BY x.prim_key
try this:
starttime and endtime are derived columns, you cannot use it in the same select statement..
You have to create a derived table then use these columns the a query outside
select name,starttime,endtime,TIME_TO_SEC( TIMEDIFF( endtime , starttime) as timediff
from(
SELECT x.name ,
( SELECT data.ts
FROM data
WHERE prim_key = x.prim_key and roll_no ='1'
) starttime ,
( SELECT data.ts
FROM woman_data
WHERE prim_key = x.prim_key and roll_no ='10'
) endtime
FROM data x
INNER JOIN y
ON x.prim_key = y.prim_key)a
ORDER BY x.prim_key
The easiest way to change a query to have an "outer-level":
SELECT
name,
starttime,
endtime,
TIME_TO_SEC( TIMEDIFF( endtime , starttime)) as timediff
FROM(
SELECT
x.prim_key,
x.name ,
( SELECT data.ts
FROM data
WHERE prim_key = x.prim_key and roll_no ='1'
) starttime ,
( SELECT data.ts
FROM woman_data
WHERE prim_key = x.prim_key and roll_no ='10'
) endtime
FROM data x
INNER JOIN y
ON x.prim_key = y.prim_key
) n
ORDER BY n.prim_key