calculate values fetched from 2 separate inline select statements - mysql

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

Related

I am missing an alias for a derived table

I know, this question has been asked very often but I know my error, I know how I could fix it, but I canĀ“t find the point where the error is. In my opinion, all the subqueries have different and unique names, I even gave the columns different names then the subqueries. Any help would be appreciated. Where is the point I am missing an alias?
Whenever I am trying to run this query I get the response "Every derived table must have its alias", which is an understandable error message, but I can't figure out where my error is located.
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM
mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
left join (
select
cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate,
avg(repRate.countedOrders) AS avgRepRate
from(
Select
*,
(
select
count(customer_email) AS csc
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS cst,
(
select
count(customer_email) AS cec
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2020-12-31'
) AS cet,
(
select
count(mso_new.customer_email) AS cnc
from
(
select
*
from
mag_sales_flat_order
where
created_at between '2018-01-01'
and current_date()
) AS mso_new
left join (
select
*
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
)) AS cnt
join (
select
customer_email,
count(grand_total) as countedOrders,
sum(grand_total) as summedOrders
from
mag_sales_flat_order
group by
customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE
store_id IN({$store['id']})
AND (
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY
entity_id;
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
LEFT JOIN
(
SELECT cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate, avg(repRate.countedOrders) AS avgRepRate
FROM
(
SELECT *,
(
SELECT count(customer_email) AS csc
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS cst,
(
SELECT count(customer_email) AS cec
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2020-12-31'
) AS cet,
(
SELECT count(mso_new.customer_email) AS cnc
FROM
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2018-01-01' AND getdate()
) AS mso_new
LEFT JOIN
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
) AS cnt
) as cl
JOIN
(
SELECT customer_email, count(grand_total) as countedOrders, sum(grand_total) as summedOrders
FROM mag_sales_flat_order
GROUP BY customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE store_id IN({ $ store ['id'] })
AND
(
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY entity_id;

why is time differences using alias not working?

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````

Query runs fast, but stored procedure is slow - Tried multiple things

I have a stored procedure which queries values from 2 tables (message and message_archived) which contain many data.
CREATE PROCEDURE `get_all_message_report`(IN fromDate TIMESTAMP, IN toDate TIMESTAMP, IN period VARCHAR(15))
BEGIN
DECLARE lfromDate TIMESTAMP;
DECLARE ltoDate TIMESTAMP;
DECLARE lperiod VARCHAR(15);
DECLARE dateFormat VARCHAR(15);
SET lfromDate = fromDate;
SET ltoDate = toDate;
SET lperiod = period;
SET dateFormat = "";
IF lperiod = "monthly"
THEN
SET dateFormat = '%b';
ELSEIF lperiod = "daily"
THEN
SET dateFormat = '%Y-%c-%d';
ELSEIF lperiod = "weekly"
THEN
SET dateFormat = '%x-%v';
END IF;
CREATE TABLE tempMessages(
id bigint(20),
generated_time timestamp,
direction varchar(255),
status varchar(255),
read_status varchar(50),
type varchar(255),
from_number varchar(255),
to_number varchar(255),
INDEX ind (id,generated_time)
);
INSERT INTO tempMessages(id,generated_time,direction,status,read_status,type,from_number,to_number)
SELECT id,generated_time, direction, status, read_status, type, from_number, to_number
FROM (
SELECT id,generated_time, direction, status, read_status, type, from_number, to_number
FROM message WHERE generated_time BETWEEN lfromDate AND ltoDate
union all
SELECT id,generated_time, direction, status, read_status, type, from_number, to_number
FROM message_archived WHERE generated_time BETWEEN lfromDate AND ltoDate
) t;
SELECT
sentMessageTable.date,
IFNULL(sentMessageTable.sentcount, 0) AS sentMessageCount,
IFNULL(newPassMessagesTable.newpassmessagescount, 0) AS newPassMessagesCount,
IFNULL(newReviewMessagesTable.newreviewmessagescount, 0) AS newReviewMessagesCount,
IFNULL(newFailMessagesTable.newfailmessagescount, 0) AS newFailMessagesCount,
IFNULL(respondedPassThreadsTable.respondedpassthreadcount, 0) AS passThreadsRespondedCount,
IFNULL(respondedReviewThreadsTable.respondedreviewthreadcount, 0) AS reviewThreadsRespondedCount,
IFNULL(respondedFailThreadsTable.respondedfailthreadcount, 0) AS failThreadsRespondedCount
FROM
(
(
/* sent message count*/
SELECT
date,
sum(sentcount1) AS sentcount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date,
COUNT(*) AS sentcount1
FROM tempMessages
WHERE direction = 'outgoing' and status in ('SENT','DELIVERED')
GROUP BY date
) t
GROUP BY date
ORDER BY date
) AS sentMessageTable LEFT JOIN
/* new pass messages count */
(
SELECT
date1,
sum(newpassmessagescount1) AS newpassmessagescount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date1,
COUNT(*) AS newpassmessagescount1
FROM tempMessages
WHERE direction='incoming'
AND read_status='UNREAD' AND type='PASS'
GROUP BY date1
) t
GROUP BY date1
ORDER BY date1
)
AS newPassMessagesTable
ON sentMessageTable.date=newPassMessagesTable.date1
LEFT JOIN
/* new review messages count */
(
SELECT
date2,
sum(newreviewmessagescount1) AS newreviewmessagescount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date2,
COUNT(*) AS newreviewmessagescount1
FROM tempMessages
WHERE direction='incoming'
AND read_status='UNREAD' AND type='REVIEW'
GROUP BY date2
) t
GROUP BY date2
ORDER BY date2
)
AS newReviewMessagesTable
ON sentMessageTable.date=newReviewMessagesTable.date2
LEFT JOIN
/* new fail messages count */
(
SELECT
date3,
sum(newfailmessagescount1) AS newfailmessagescount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date3,
COUNT(*) AS newfailmessagescount1
FROM tempMessages
WHERE direction='incoming'
AND read_status='UNREAD' AND type='FAIL'
GROUP BY date3
) t
GROUP BY date3
ORDER BY date3
)
AS newFailMessagesTable
ON sentMessageTable.date=newFailMessagesTable.date3
LEFT JOIN
/* responded pass thread count*/
(
SELECT
date4,
count(*) AS respondedpassthreadcount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date4,
from_number,
to_number,
COUNT(*),
MAX(msg.id) AS maxId
FROM tempMessages msg
GROUP BY date4, msg.from_number, msg.to_number
HAVING maxId IN
(
SELECT max(msg.id)
FROM tempMessages msg
WHERE msg.direction = "outgoing"
GROUP BY DATE_FORMAT(generated_time, dateFormat), msg.from_number, msg.to_number
) AND maxId NOT IN (SELECT MIN(msgSub.id)
FROM tempMessages msgSub
GROUP BY msgSub.from_number, msgSub.to_number
HAVING MIN(msgSub.id) = MAX(msgSub.id))
AND from_number IN ( select msg1.to_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='PASS')
AND to_number IN ( select msg1.from_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='PASS')
) t
GROUP BY date4
ORDER BY date4
) AS respondedPassThreadsTable
ON sentMessageTable.date = respondedPassThreadsTable.date4
LEFT JOIN
/* responded review thread count*/
(
SELECT
date5,
count(*) AS respondedreviewthreadcount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date5,
from_number,
to_number,
COUNT(*),
MAX(msg.id) AS maxId
FROM tempMessages msg
GROUP BY date5, msg.from_number, msg.to_number
HAVING maxId IN
(
SELECT max(msg.id)
FROM tempMessages msg
WHERE msg.direction = "outgoing"
GROUP BY DATE_FORMAT(generated_time, dateFormat), msg.from_number, msg.to_number
) AND maxId NOT IN (SELECT MIN(msgSub.id)
FROM tempMessages msgSub
GROUP BY msgSub.from_number, msgSub.to_number
HAVING MIN(msgSub.id) = MAX(msgSub.id))
AND from_number IN ( select msg1.to_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='REVIEW')
AND to_number IN ( select msg1.from_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='REVIEW')
) t
GROUP BY date5
ORDER BY date5
) AS respondedReviewThreadsTable
ON sentMessageTable.date = respondedReviewThreadsTable.date5
LEFT JOIN
/*responded fail thread count*/
(
SELECT
date6,
count(*) AS respondedfailthreadcount
FROM
(
SELECT
DATE_FORMAT(generated_time, dateFormat) AS date6,
from_number,
to_number,
COUNT(*),
MAX(msg.id) AS maxId
FROM tempMessages msg
GROUP BY date6, msg.from_number, msg.to_number
HAVING maxId IN
(
SELECT max(msg.id)
FROM tempMessages msg
WHERE msg.direction = "outgoing"
GROUP BY DATE_FORMAT(generated_time, dateFormat), msg.from_number, msg.to_number
) AND maxId NOT IN (SELECT MIN(msgSub.id)
FROM tempMessages msgSub
GROUP BY msgSub.from_number, msgSub.to_number
HAVING MIN(msgSub.id) = MAX(msgSub.id))
AND from_number IN ( select msg1.to_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='FAIL')
AND to_number IN ( select msg1.from_number
from tempMessages msg1
where msg1.direction = 'incoming' and msg1.type='FAIL')
) t
GROUP BY date6
ORDER BY date6
) AS respondedFailThreadsTable
ON sentMessageTable.date = respondedFailThreadsTable.date6
DROP TABLE tempMessages;
END
Instead of creating a normal table i tried using temporary tables
But i can't join a temp table multiple times in same query.
So i tried using normal table which deletes after execution of the sp
but it is also not helping to reduce the loading time.
while executing the query in sp separately i get result in 10-20 seconds
Any solution to reduce loading time ?

Mysql - Access column from grandparent's joined table in WHERE in subquery inside parent's FROM

Inside a WHERE inside a subquery inside a FROM inside another subquery inside a SELECT that's joined to another table, I need to access a column from that joined table.
edited to add more complete example:
SELECT
field_one,
field_two,
field_three,
field_one-field_three AS field_five,
field_six
FROM (
SELECT
IFNULL(
(
SELECT
SUM(us.field_seven) AS field_one
FROM
table_one us
WHERE
us.rto_id = rto.relevant_field_one
AND
us.created >= (
SELECT
IF(
selected_date IS NULL,
MIN(created),
selected_date
)
FROM (
SELECT
IF(
latest_date < DATE_SUB(CURDATE(), INTERVAL rtt.relevant_field_two DAY),
CURDATE(),
MAX(prevdate)
) AS selected_date,
created
FROM (
SELECT
created,
#calc_prevdate as prevdate,
DATEDIFF(#calc_prevdate, created) AS diff,
#calc_prevdate := created
FROM (
SELECT
sto.created
FROM
table_one sto
WHERE
sto.rto_id = rto.relevant_field_one
UNION ALL
SELECT
stt.created
FROM
table_two stt
WHERE
stt.rto_id = rto.relevant_field_one
ORDER BY
created DESC
) AS x
CROSS JOIN (
SELECT
#calc_prevdate := NULL
) as vars
) AS z
CROSS JOIN (
SELECT
MAX(created) AS latest_date
FROM(
SELECT
sto.created
FROM
table_one sto
WHERE
sto.rto_id = rto.relevant_field_one
UNION ALL
SELECT
stt.created
FROM
table_two stt
WHERE
stt.rto_id = rto.relevant_field_one
ORDER BY
created DESC
) as z
) AS y
WHERE
diff > rtt.relevant_field_two
) as w
)
GROUP BY us.rto_id
),0
) AS field_one,
IFNULL(
(
SELECT
SUM(tt.field_seven) AS field_three
FROM
table_two tt
WHERE
tt.rto_id = rto.relevant_field_one
AND
tt.created >= (
SELECT
IF(
selected_date IS NULL,
MIN(created),
selected_date
)
FROM (
SELECT
IF(
latest_date < DATE_SUB(CURDATE(), INTERVAL rtt.relevant_field_two DAY),
CURDATE(),
MAX(prevdate)
) AS selected_date,
created
FROM (
SELECT
created,
#calc_prevdate as prevdate,
DATEDIFF(#calc_prevdate, created) AS diff,
#calc_prevdate := created
FROM (
SELECT
sto.created
FROM
table_one sto
WHERE
sto.rto_id = rto.relevant_field_one
UNION ALL
SELECT
stt.created
FROM
table_two stt
WHERE
stt.rto_id = rto.relevant_field_one
ORDER BY
created DESC
) AS x
CROSS JOIN (
SELECT
#calc_prevdate := NULL
) as vars
) AS z
CROSS JOIN (
SELECT
MAX(created) AS latest_date
FROM(
SELECT
sto.created
FROM
table_one sto
WHERE
sto.rto_id = rto.relevant_field_one
UNION ALL
SELECT
stt.created
FROM
table_two stt
WHERE
stt.rto_id = rto.relevant_field_one
ORDER BY
created DESC
) as z
) AS y
WHERE
diff > rtt.relevant_field_two
) as w
)
GROUP BY tt.rto_id
), 0
) AS field_three,
IFNULL(
(
SELECT
COUNT(*) AS field_two
FROM
table_two tt
WHERE
tt.rto_id = rto.relevant_field_one
GROUP BY tt.rto_id
), 0
) AS field_two,
IFNULL(
(
SELECT
GREATEST(
IFNULL(MAX(us.created), 0), IFNULL(MAX(tt.created), 0)
) AS field_six
FROM
table_one us
LEFT JOIN
table_two tt ON us.rto_id = tt.rto_id
WHERE
us.rto_id = rto.relevant_field_one
GROUP BY us.rto_id
), 0
) AS field_six
FROM
relevant_table_one rto
LEFT JOIN
relevant_table_two rtt ON rto.rtt_id = rtt.id
WHERE
rto.rtt_id = ?
GROUP BY rto.relevant_field_one
) v
ORDER BY id ASC;
given that query, I need to access relevant_table_one.relevant_field_one and relevant_table_two.relevant_field_two from inside the subqueries, but the restrictions on subqueries dictates that you cant access a parents table in a subquery inside a FROM
I managed to solve this (so far I think) by adding #rfo := relevant_field_one and #rft := relevant_field_two up in the select where they were accessable and then referring to the created variables instead of the columns down in the nested query where relevant.
It's possible I'm just getting false positives but so far the solution appears to be working.

Update table from complicated select and inner join statement - tsql

This code works really well for an initial insert into a table. But now i need to be able to do ongoing updates to append new rows to a table... Do I need to do a SET for each item I'm inserting. I've tried doing that, actually, and it still complains.
CREATE TABLE dbo.Calcs
(
OutageDate DATE,
StartTime TIME(7),
EndTime TIME(7),
Duration INT
);
INSERT dbo.Calcs SELECT '20101110', '16:00', '17:30', 90;
INSERT dbo.Calcs SELECT '20101111', '13:00', '14:02', 62;
INSERT dbo.Calcs SELECT '20101112', '17:00', '18:00', 60;
INSERT dbo.Calcs SELECT '20101113', '16:05', '16:25', 20;
INSERT dbo.Calcs SELECT '20101114', '16:59', '18:01', 62;
INSERT dbo.Calcs SELECT '20101115', '22:15', '01:30', 165;
CREATE TABLE dbo.TableIWantUpdated
(
OutageDate DATE,
StartHour TIME(7),
StartMinutes TIME(7),
StartTime TIME(7),
EndHour int,
EndMinutes int,
EndTime TIME(7),
Duration INT
);
;WITH n(n) AS
(
SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.objects
),
x AS
(
SELECT
o.OutageDate, StartHour = (DATEPART(HOUR, StartTime) + n.n - 1) % 24,
StartTime, EndTime, Duration,
rn = ROW_NUMBER() OVER (PARTITION BY o.OutageDate, o.StartTime ORDER BY n.n)
FROM n INNER JOIN dbo.Calcs AS o
ON n.n <= CEILING(DATEDIFF(MINUTE, CONVERT(DATETIME, StartTime),
DATEADD(DAY, CASE WHEN EndTime < StartTime THEN 1 ELSE 0 END,
CONVERT(DATETIME, EndTime)))/60.0)
),
mx AS (SELECT OutageDate, StartTime, minrn = MIN(rn), maxrn = MAX(rn)
FROM x GROUP BY OutageDate, StartTime)
-- I want to use the below inner join from the CTE to update a table now
UPDATE [dbo].[TableIWantUpdated]
SELECT
x.OutageDate,
x.StartHour,
StartMinutes = CASE
WHEN x.rn = mx.minrn THEN DATEPART(MINUTE, x.StartTime) ELSE 0 END,
EndHour = x.StartHour + 1,
EndMinutes = CASE
WHEN x.rn = mx.maxrn THEN DATEPART(MINUTE, x.EndTime) ELSE 0 END,
x.StartTime,
x.EndTime,
x.Duration
--this is where I did the initial insert of data...but now I want it to be able to update
--INTO [dbo].[TableIWantUpdated] FROM x INNER JOIN mx
FROM x INNER JOIN mx
ON x.OutageDate = mx.OutageDate
AND x.StartTime = mx.StartTime
ORDER BY x.OutageDate, x.rn;
GO
INSERT INTO should work, then. I'm also removing the ORDER BY at the bottom.
;WITH n(n) AS
(
SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.objects
),
x AS
(
SELECT
o.OutageDate, StartHour = (DATEPART(HOUR, StartTime) + n.n - 1) % 24,
StartTime, EndTime, Duration,
rn = ROW_NUMBER() OVER (PARTITION BY o.OutageDate, o.StartTime ORDER BY n.n)
FROM n INNER JOIN dbo.Calcs AS o
ON n.n <= CEILING(DATEDIFF(MINUTE, CONVERT(DATETIME, StartTime),
DATEADD(DAY, CASE WHEN EndTime < StartTime THEN 1 ELSE 0 END,
CONVERT(DATETIME, EndTime)))/60.0)
),
mx AS (SELECT OutageDate, StartTime, minrn = MIN(rn), maxrn = MAX(rn)
FROM x GROUP BY OutageDate, StartTime)
-- I want to use the below inner join from the CTE to update a table now
INSERT INTO [dbo].[TableIWantUpdated]
SELECT
x.OutageDate,
x.StartHour,
StartMinutes = CASE
WHEN x.rn = mx.minrn THEN DATEPART(MINUTE, x.StartTime) ELSE 0 END,
EndHour = x.StartHour + 1,
EndMinutes = CASE
WHEN x.rn = mx.maxrn THEN DATEPART(MINUTE, x.EndTime) ELSE 0 END,
x.StartTime,
x.EndTime,
x.Duration
--this is where I did the initial insert of data...but now I want it to be able to update
--INTO [dbo].[TableIWantUpdated] FROM x INNER JOIN mx
FROM x INNER JOIN mx
ON x.OutageDate = mx.OutageDate
AND x.StartTime = mx.StartTime
--ORDER BY x.OutageDate, x.rn;
GO