Next value of the decrements sequence - mysql

I have a scenario have to get the next decrements sequence.
Example of scenario i attached the below image.
My output i have given the image it is base on the
1. Statuseq should decrements then the other values.

SELECT taskNumber, assignedTo, statusSeq
FROM
( SELECT (#statusPre > statusSeq) AS statusChanged
, taskNumber, assignedTo, statusSeq
, #statusPre := statusSeq
FROM task
, (SELECT #statusPre:=NULL) AS d
where taskNumber = 'R3-09-5352'
ORDER BY endDate asc
) AS good
WHERE statusChanged;

Related

sql rank row results

I"m trying to add a new col that shows the rank (or sequence) of row results by date.
I've written:
SELECT
#row_number:=(CASE
WHEN #member_id = lh.member_id and lc.ladder_advocacy is not null
THEN #row_number + 1
when #member_id = lh.member_id and lc.ladder_advocacy is null then "null"
ELSE 1 /* there is an error here - i need it to return a 1 if not null, then 2 for the 2nd instance, etc */
END) AS rank_advocacy,
#member_id:=lh.member_id AS member_id,
lh.ladder_change,
lc.name,
lc.ladder_advocacy,
lc.ladder_elected,
lc.ladder_policy,
lc.ladder_engagement,
lc.ladder_newventure,
lc.ladder_collective,
lc.is_trigger
FROM
leenk_ladder_history AS lh
LEFT JOIN
leeds_so.leenk_ladder_config AS lc ON lh.ladder_config_id = lc.id
WHERE
ladder_change = 1 AND trigger_active = 1
ORDER BY member_id, trigger_event_date DESC;
There is an error at row 4, and I'm not sure how to fix it. For the first result, I want to return 1. for the second results, I want to return #row_number + 1. Third result, #row_number+2 (etc).
How do I achieve this?
I don't understand how the condition lc.ladder_advocacy is not null is being used. However, the basic structure is:
SELECT (#row_number = IF(#member_id = lh.member_id, #row_number + 1
IF(#member_id := lh.member_id, 1, 1)
)
) as rank_advocacy,
lh.ladder_change,
. . .
Some really important points:
You need to assign #member_id and #row_number in the same expression. MySQL (as with all other databases) does not guarantee the order of evaluation of expressions.
In more recent versions of MySQL, I think the ORDER BY needs to go in a subquery, with the variable expressions in the outer query.

Determine if date range is contained in another range in MySQL

I'm looking for a method to do this in a "clean" way (not 3..n cross JOINS), just want to know if it's possible to do it in sql, if not I'll go for another solution.
Will use numbers instead of dates for simplification
I have n rows with n tasks and n items
task item start end
1 1 1 5
1 2 2 6
1 3 0 4
1 4 8 10
In this case I'm looking to use the min(start) max(end) of the overlapping dates so the result will be:
task item start end
1 1,2,3 0 6
1 4 8 10
Any ideas of how to resolve it in sql? is like a challenge, if can't do it this way I'll go to python.
Thank you
This similar to the problem I answered here, and similar data "island" problems. However, it is more complicated in your case as the identification of the "islands" will need to be calculated from more than just the record immediately prior.
It will end up looking something like this:
SET #iEnd = -1; /* init value should be something you don't expect to see */
SET #task = -1; /* init value should be something you don't expect to see */
SET #isNewIsland = 0 /* init value doesn't actually matter */;
SET #i = 0;
SELECT islandNum
, GROUP_CONCAT(item ORDER BY item) AS items
, MIN(start) AS iStart
, MAX(end) AS iEnd
FROM (
SELECT #isNewIsland := IF(#task <> task OR start > #iEnd, 1, 0)
, #task := task, item, start, end
, #i := IF(#isNewIsland = 1, #i + 1, #i) AS islandNum
, #end := IF(#isNewIsland = 1, end, GREATEST(end, #iEnd))
FROM ( /* Session(#) variables evaluation can be a bit unpredictable
the subquery helps guarantee ordering before evaluation */
SELECT task, item, start, end
FROM theTable
ORDER BY task, start, end
) AS subQ
) AS subQ 2
some are not fond of needing the separate, preceding SET statements; to avoid the need, replace ) AS subQ with
) AS subQ, (SELECT #iEnd := -1, #task := -1, #isNewIsland := 0, #i := 0) AS sInit

Convert time "28:45" to "4:45" MySQL

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

Group by changing boolean value

Hi i have the following SQL question:
SELECT station_id, filling_station_status,date_created ,
case when filling_station_status="FREE" then 0
else 1 end as status
FROM efahrung.electric_station_time_status
where station_id=11
In my table have a column filling_station_status.
It can be "FREE" or "IN_USE".
I want to group elements so, that if the filling_station_status is changed (from "FREE" to "IN_USE") it will create a date range in my case, date_created.
In the next change again from ("IN_USE" to "FREE") it creates a new date range.
Thanks for a suggestions.
If you just need SQL query to generate date range in output, then try this:
Select s.station_id,
Coalesce(e.filling_station_status, s.filling_station_status) fillingStationStatus,
case e.filling_station_status
when "FREE" then 0 else 1 end status,
s.date_created startDate,
e.date_created endDate
From efahrung.electric_station_time_status s
Left Join efahrung.electric_station_time_status e
On e.station_id = s.station_id
and s.filling_station_status = 'IN_USE'
and e.filling_station_status = 'FREE'
and e.date_created =
(Select Min(date_created)
From efahrung.electric_station_time_status
Where station_id = s.station_id
and date_created > s.date_created)

Trying to merge multiple UPDATE statements into one within SQL stored procedure

I have multiple update statements in a stored procedure (as shown below).
Question is I am trying to combine them into one UPDATE statement as there is a performance issue (takes longer to execute stored procedure). I tried putting columns (such as PONUMBER, VENDORID etc) in a single update statement but it is throwing errors.
Please suggest.
UPDATE rptMaster SET PONUMBER = (select top 1 poMaster.PONUMBER from poMaster where poMaster.ITEMNMBR =rptMaster.ITEMNMBR and
poMaster.UnCommited > 0)
UPDATE rptMaster SET VENDORID = (select top 1 poMaster.VENDORID from poMaster where poMaster.ITEMNMBR =rptMaster.ITEMNMBR and
poMaster.UnCommited > 0)
UPDATE rptMaster SET DUEDATE = (select top 1 poMaster.REQDATE from poMaster where poMaster.ITEMNMBR =rptMaster.ITEMNMBR and
poMaster.UnCommited > 0)
UPDATE rptMaster SET POQTYORDER = (select top 1 (poMaster.QTYORDER / rptMaster.UOMQTY) from poMaster where poMaster.ITEMNMBR =rptMaster.ITEMNMBR and
poMaster.UnCommited > 0)
Mine is similar to polkduran's:
WITH PO AS (
SELECT PONUMBER
, VENDORID
, REQDATE
, QTYORDER
, ITEMNMBR
, ROW_NUMBER() OVER (PARTITION BY ITEMNMBR ORDER BY ??) as RN
FROM poMaster
WHERE UnCommited > 0
)
UPDATE rptMaster
SET PONUMBER = po.PONUMBER
, VENDORID = po.VENDORID
, DUEDATE = po.REQDATE
, POQTYORDER = po.QTYORDER / rptMaster.UOMQTY
FROM rptMaster
JOIN PO
ON PO.ITEMNMBR = rptMaster.ITEMNMBR
and PO.RN = 1
I'm using a Common Table Expression (CTE) to assign a row number to each poMaster record, with the records for each value of ITEMNMBR numbered separately. This allows us to pick to the first record for each ITEMNBR in our JOIN, later, similar to the way you were using Top 1 in your subqueries.
Please note, though: because you didn't indicate how you wanted to select the Top 1 record in your query, I had to leave the ORDER BY clause in the CTE unspecified. (I put ?? in as a placeholder.) You need to specify one or more sort fields in place of the ?? so it knows how to sort and number the records.
You can make an update using a join clause:
update rpt
set
PONUMBER = po.PONUMBER,
VENDORID = po.VENDORID,
DUEDATE = po.REQDATE,
POQTYORDER = (po.QTYORDER / rpt.UOMQTY)
from rptMaster rpt
inner join poMaster po
on po.ITEMNMBR = rpt.ITEMNMBR
where po.UnCommited > 0
I don't have a way to test it right now but that might work.