I have a table with 50 records.
In that table, I just added a column name Number (int). For each of those 50 records the current value is (NULL).
How can I make a simple query ( LOOP ) which will go through all those records (rows) and for each set the row number example (1, 2, 3, 4, 5)
You can use variables with update. If you don't care about the ordering:
update t cross join
(select #rn := 0) params
t.number = (#rn := #tn + 1);
Alternatively, you could create a new table with an auto-increment column and load the data into that table. That way, new records will also be assigned new numbers.
Related
I have a table in MySQL as described below
rownum,value,status
1,16,1
2,32,1
3,16,1
4,23,0
5,33,0
6,16,0
7,22,0
8,13,1
9,43,1
10,32,1
11,45,0
12,28,0
13,23,0
14,28,0
15,31,1
16,13,1
17,44,1
Here the third column shows the status of the row basis which I want to add a new column. The logic required is for every set of repeated values of 1 in column "status" the new column will get a number assigned to all of those rows. And this number will increment with +1 when the next set of 1s are found. the output table should look as below.
rownum,value,status,category
1,16,1,1
2,32,1,1
3,16,1,1
4,23,0,null
5,33,0,null
6,16,0,null
7,22,0,null
8,13,1,2
9,43,1,2
10,32,1,2
11,45,0,null
12,28,0,null
13,23,0,null
14,28,0,null
15,31,1,3
16,13,1,3
17,44,1,3
I am a bit confused on how this logic can be created and any inputs will be really helpful. Thanks!
You can achieve this in MySQL using User-defined Session variables, and using conditional functions like If(). We store previous row's status value in #stat variable, and compare it with current row's status value, to get results as intended.
But if it is just for display purposes, you should seriously consider handing this in your application code.
Nevertheless, try the following query (DB Fiddle DEMO):
SELECT
IF( dt.status = 0,
NULL,
IF( #stat = 0, #cat := #cat + 1, #cat )
) AS category,
dt.rownum,
dt.value,
#stat := dt.status AS status
FROM
(
SELECT
rownum,
value,
status
FROM your_table
ORDER BY rownum ASC
) AS dt
CROSS JOIN (SELECT #cat := 0,
#stat := 0) AS init_user_vars
I need to generate unique "ids", the catch is, it can be only between 1 - 99999.
The "good" thing is, that it has to be unique only in group with another column.
We have groups, each group has its own "group_id" and each group need something like unique('group_id', 'increment_id')
The 99999 records is enough for several years for each group right now, but it is not enough for all groups together, therefore I cant just create table with AUTO_INCREMENT and inserting there records and taking its auto increment.
For example, if I need 5 records for Group one and three records for Group two, I suppose to get something like this:
group_id, increment_id
1, 1,
1, 2,
1, 3,
1, 4,
1, 5,
2, 1
2, 2,
2, 3
Also, the conflict is not an option, therefore using something like "length" can be tricky, if done programatically (there can be i.e. 10 requests at once, each of them first select length for given group_id and then tries to create 10 rows with same increment_id)
However I am thinking - if I set it up as the value of subselect of count, than it will always be "ok"?
You can create a auxiliar table named counters to manage that:
table: counters
columns: group_id, current_counter
OR
Each time you insert a row increment_id = select max(increment_id)+1 from table_xxx where group_id = group_xxxx
You can use user variables to get the incrementing number within each group_id:
select
t.*,
#rn := if(#group_id = group_id,
#rn + 1,
if(#group_id := group_id, 1, 1)
) increment_id
from (
select group_id
from your_table t
/* some where clauses */
order by group_id
) t
cross join (
select #rn := 0,
#group_id := - 1
) t2
I have a table in mysql which has a column filled with text values, lets say pets. So I would have a column pets with values like: "cat", "dog", "turtle", "cat", "cat", "turtle". In reality there are hundreds of thousands of different pet types in that column, but many repeats.
What I would like to do is create a second column which has an index for each entry in the first column. So for instance, in the above case, we would assign 'cat' the id of 1, 'dog' an id of 2, 'turtle' of 3 etc. and end up with a column with the values: 1, 2, 3, 1, 1, 3
Is there a way to do this? (preferably a quick way as the table is over 7 million rows).
Create a new table with the lookup values. You can do this easily:
create table PetTypes as
select (#rn := #rn + 1) as pettypeid, pettype
from (select distinct pettype from pets) p cross join
(select #rn := 0) params;
Then you can readily add, update, or just use the column in the select:
alter table pets add petttypeid int;
update pets p join
pettypes pt
on p.pettype = pt.pettype
set p.pettypeid = pt.pettypeid;
I would then recommend that you remove the pettype column from the original table.
Note: you can do the above without making a new table. But I think creating a new lookup table for this column is the right way to go.
I am trying to find a way to re-sequence the content of a column after deletions leave a missing value.
The troubles..
1 - the values are not unique, but can repeat any number of times, so SORT and ROW_NUMBER won't work.
2 - the values are not sequential in presentation, they can appear in any order, but must always -as a whole- progress from 1 to the maximum value without any gaps.
A visual of what I am trying to accomplish..
ID, Case, Othercols
1, 1, data
2, 3, data
6, 5, data
8, 3, data
I need to create a procedure to find the missing values in Case and pull all higher values down to fill in the gaps.
ID, Case, OtherCols
1, 1, data
2, 2, data
6, 3, data
8, 2, data
I know there are better ways to resolve the issue than this, but the database is part of a server so I cannot change how it operates, only the content, and even that only at specific times.
I am only able to remove the 'failed' data and re-sequence (so far by hand) to get the software to take the result as valid.
If I understand correctly, you can resequence the values using variables:
select case, (#rn := #rn + 1) as newval
from (select distinct case from table t order by case) t cross join
(select #rn := 0) vars;
With this as a lookup table, you can then renumber the values:
update table t join
(select case, (#rn := #rn + 1) as newval
from (select distinct case from table t order by case) t cross join
(select #rn := 0) vars
) tt
on t.case = tt.case
set t.case = tt.newval;
Note: this uses case as a column name even though that is not allowed in MySQL.
I have a table T with some data having 3 rows. Now I added a new column c.
Now I want to insert values into c for existing rows.
I do it like this :
insert into T (c) values(1),(2),(3);
But instead of updating existing data, it inserted new rows.
How can I update existing data ?
I don't want to specify where clause. I just want to add values serial wise as insert does.
You would use the UPDATE statement to assign values to columns of existing rows.
UPDATE t
SET t.c = 1
WHERE t.a = 1 ;
To assign unique, sequential integer to each existing row, you'd need to make use of the primary key, or a unique identifier from each row. In this example, we assume that the id column is unique:
UPDATE t
JOIN ( SELECT r.id
, #i := #i + 1 AS i
FROM t r
JOIN (SELECT #i := 0) n
ORDER BY r.id
) s
ON s.id = t.id
SET t.c = s.i
Actually, you can also do this:
UPDATE t
JOIN ( SELECT #i := 0 ) n
SET t.c = #i := #i + 1
ORDER BY t.id
It sounds like you might want to investigate the AUTO_INCREMENT attribute.
You can use below query
UPDATE Table
SET Col1='1', Col2='2'
and so on...
Also, you can use where condition, if you want to update data with some specified conditions, as below:
---it's just an example of query used in my database---
UPDATE City_Employee
SET City='Banglore' where (City='Delhi')
Best of luck !