What I try to do is to make the first 200 records from a column to start from 1 to 200. After 200 records no changing on values.
The current records look like this
1
2
3
4
4
6
6
...
What I need is to update them to be
1
2
3
4
5
...
200
What sql statement do I need to fix them?
Initialize a user defined variable and do it like this:
SET #rownumber = 0;
UPDATE your_table
SET your_column = (#rownumber := #rownumber + 1)
ORDER BY the_column_that_defines_the_order_of_the_first_200_records
LIMIT 200;
Related
I have a table,
Name Seconds Status_measure
a 0 10
a 10 13
a 20 -1
a 30 15
a 40 20
a 50 12
a 60 -1
Here I want for a particular name a new column which is calculated by, "The number of times the value goes >-1 only after once the -1 is met" . So in this particular data I want a new column for the name "a" which has the value=3 , because once the -1 is reached in Status_measure, we have 3 values (15 and 20 and 12)>-1
Required data frame:
Id Name Seconds Status_measure Value
1 a 0 10 3
2 a 10 13 3
3 a 20 -1 3
4 a 30 15 3
5 a 40 20 3
6 a 50 12 3
7 a 60 -1 3
I tried doing
count(status_measure>-1) over (partition by name order by seconds)
But this is not giving any desired result
You can do it in 2 steps, group data, count entries of the grp = 1.
select *, sum(Status_measure > -1 and grp = 1) over(partition by name) n
from (
select *
, row_number() over(partition by name order by Seconds) - sum(Status_measure > -1 ) over(partition by name order by Seconds) grp
from tbl
) t
An option is using a variable update, which:
starts from 0
increases its value when reaches a -1
decreases its value when reaches a second -1
Once you have this column, you can run a sum over your values.
SET #change = 0;
SELECT *, SUM(CASE WHEN Status_measure = -1
THEN IF(#change=0, #change := #change + 1, #change := #change - 1)
ELSE #change END) OVER() -1 AS Value_
FROM tab
Check the demo here.
Limitations: this solution assumes you have only one range of interesting values between -1s.
Note: there's a -1 decrement from your sum because the first update of the variable will leave 1 in the same row of -1, which you don't want. For better understanding, comment out the application of SUM() OVER and see intermediate output.
More of a clarification to your question first. I want to expand your original data to include another row for the sake of 2 vs 3 entries. Also, is there some auto-increment ID in your data that the sequential consideration is applicable such as
Id Name Seconds Status_measure Value
1 a 0 10 3
2 a 10 13 3
3 a 20 -1 3
4 a 30 15 3
5 a 40 20 3
6 a 50 12 3
7 a 60 -1 3
If sequential, and you have IDs 1 & 2 above the -1 at ID #3. This would indicate two entries. But then for IDs 4-6 above -1 have a count of three entries before ID #7.
So, what "VALUE" do you want to have in your result. The max count of 3 for all rows, or would it be a value of 2 for ID#s 1, 2 and 3? And value of 3 for Ids 4-7? Or, do you want ALL entries to recognize the greatest count before -1 measure to show 3 for all entries.
Please EDIT your question, you can copy/paste this in your original question if need be and provide additional clarification as requested (auto-increment as well as that is an impact of final output / determining break).
I have a table named Table1 that looks like this
ID VALUES
1 050
2 50
3 100
4 010
5 300
I need to update the targeted value through the ID. In this case I want to remove leading 0 where ID is 1. This is the end result below:
ID VALUES
1 50
2 50
3 100
4 010
5 300
Bear in mind that Id 4 is remained the same. As I have only specified Id 1 to remove that zero.
Reason I want to do this way, is because I wan't to learn how to remove the leading zero and at the same time how I can remove the leading zero for a specific ID.
You can use TRIM to update the values in your table:
UPDATE Table1
SET `values` = TRIM(LEADING '0' FROM `values`)
WHERE id = 1;
SELECT * FROM Table1
Output:
id values
1 50
2 50
3 100
4 010
5 300
Demo on dbfiddle
You can try below
update tablename set value=substr(value,2,length(value)-1)
where id=1
Please try this
SELECT `id`,
(CASE
WHEN (LEFT(`values`,1) = 0 AND `id` = 1) THEN SUBSTR(`values`,2)
ELSE
`values`
END
) `values`
FROM `data`
DEMO
I have a table like this
id Bill No Branches_id
1 1 1
2 2 1
3 3 1
4 1 2
5 4 1
when user deletes bill no 2 all other record's bill_no update in numerical order like this
id Bill No Branches_id
1 1 1
3 2 1
4 1 2
5 3 1
is there any easy way to reorder all records without a loop in programmatically
It appears that id is the primary key and you want to update another column within each bill. This can be reasonable.
You can use variables:
declare #rn := 0;
update likethis lt
set bill_no = (#rn := #rn + 1)
where lt.branches_id = 1
order by lt.id;
Note that all foreign references to the table should be using id. If bill_no is used to connect to another table, then you shouldn't change the value (even with cascading foreign keys), unless this is a very rare occurrence.
I was looking for a query that sums the top n values for each user. Fortunately, I found the solution in this post Sum top 5 values in MySQL
However, I'm having a harsh time understanding the given solution which is :
SELECT driver, SUM(`position`)
FROM (SELECT driver, race, season, `position`,
IF(#lastDriver=(#lastDriver:=driver), #auto:=#auto+1, #auto:=1) indx
FROM results, (SELECT #lastDriver:=0, #auto:=1) A
ORDER BY driver, `position`) AS A
WHERE indx <= 5
GROUP BY driver ;
Can someone explain how it works especially the subquery after the FROM Clause ?
Thank you in advance.
The MySQL #variables are like doing an inline program of setting a variable, comparing and then using the result as basis for next row being compared... Let me re-format your query for a little better following / readability.
SELECT
driver,
SUM(`position`)
FROM
( SELECT
driver,
race,
season,
`position`,
IF( #lastDriver = ( #lastDriver := driver),
#auto := #auto + 1,
#auto := 1) indx
FROM
results,
(SELECT #lastDriver := 0,
#auto := 1) A
ORDER BY
driver,
`position`) AS A
WHERE
indx <= 5
GROUP BY
driver ;
The inner "From" clause starts the query. The Select # is like you having a program that does..
set #auto = 1
set #lastDriver = 0
to prepare the variables.
Because you have an order by clause the query will grab records from the "results" table and put them in order. This is like a queue of records ABOUT to be processed. Now, think of the query running all the records through a do/while loop. Remember, your #auto = 1 and #lastDriver = 0 to start.
Now, the query will process the records in order, and as it goes ONE FIELD AT A TIME is like the query saying...
Add the driver to the result
add the race to the result
add the season to the result
add the `position` to the result
Now for what you are probably waiting for... what is going on with the IF() and # variables. The IF() is like the following
IF( some condition )
add this value to the result
else
add this value to the result
In this case, the #lastDriver = ( #lastDriver := driver ) is pseudo something like..
set HoldLastDriver = #lastDriver
set #lastDriver = the driver of the current record being processed
if( HoldLastDriver = new value of #lastDriver -- current record driver )
set the auto value = auto value +1
else
set the auto value back to 1 because the driver just changed
The result of this is put into the "indx" column.
So, now, when it gets to the next row, the #lastDriver and #auto have been updated and continue from there... So, if you have the following data, the list will show what the values might be of just showing the driver and auto columns as this is the basis of the as that is the critical element for the query.
BEFORE ROW PROCESSED AFTER ROW PROCESSED
driver pos/race/season #lastDriver #auto #lastDriver #auto
1 3 / A / A 0 1 1 1
1 3 / B / A 1 1 1 2
1 4 / D / B 1 2 1 3
1 5 / E / D 1 3 1 4
1 7 / F / D 1 4 1 5
1 7 / G / D 1 5 1 6
2 2 / A / A 1 6 2 1
2 2 / B / A 2 1 2 2
3 1 / A / A 2 2 3 1
3 2 / B / A 3 1 3 2
3 2 / D / B 3 2 3 3
3 2 / E / D 3 3 3 4
3 3 / F / D 3 4 3 5
3 3 / G / D 3 5 3 6
To end the query, now that all these records are processed, your outer query will process the driver and sum() but only for the records where "indx" (the AFTER version of #auto) is less or equal to 5... so the two records where #auto was 6 (driver 1 & 3) would NOT be considered in the result summation.
How can I write an sql to tell mysql to fetch the next five records starting from 5 limit 5 from a table like below.
srt_id (this is not the auto increment column even though the value is incremented)
------
1
2
3
4
5
6
7
8
9
10
So over here, I'd like to begin at 6 then end at 10. I might even want to begin at 6 or 7 or 8. I can't use offset 5 or something like that. I have to start at that row and fetch the rest. Can u pls help?
So, I tried:
select * from table where srt_id = 5 limit 5; //Begin at 5 and the next 5 records
select * from table where srt_id >= 5 order by srt_id limit 5;