If I have two tables...
table_x table_y
| location | latitude | | location | min_latitude | max_latitude |
| -------- | -------- | | -------- | ------------ | ------------ |
| | 41.5 | | point_x | 41.0 | 42.0 |
How do I set table_x.location to table_y.location if table_x.latitude is in between table_y.min_latitude and table_y.max_latitude? I tried the code below but it cannot recognize table_y.
UPDATE table_x
SET table_x.location = table_y.location
WHERE table_x.latitude BETWEEN table_y.min_latitude AND table_y.max_latitude
In your query, table_y comes from nowhere.
Try this:
UPDATE table_x x
JOIN table_y y
ON x.latitude BETWEEN y.min_latitude AND y.max_latitude
SET x.location = y.location
you need to join the second table
But as many rows can be selected for update, you should test this prior of running the query
UPDATE table_x,table_y
SET table_x.location = table_y.location
WHERE table_x.latitude BETWEEN table_y.min_latitude AND table_y.max_latitude
Related
I have a MySQL table including following columns :
+------------+-------------+
| auto_no | auto_no_new |
+------------+-------------+
| 2021-10431 | 20577 |
| 2021-10432 | 20578 |
| 2021-10433 | 20579 |
| 2021-10434 | 20580 |
| 2021-10435 | 20581 |
| 2021-10436 | 20582 |
+------------+-------------+
Value in the "auto_no" column increments with relevant year. The values show in the table started previously and changed at the beginning of the year as above. Then I needs to start the values in the "auto_no" columns as follows :
+------------+-------------+
| auto_no | auto_no_new |
+------------+-------------+
| 2021-00001 | 20577 |
| 2021-00002 | 20578 |
| 2021-00003 | 20579 |
| 2021-00004 | 20580 |
| 2021-00005 | 20581 |
| 2021-00006 | 20582 |
+------------+-------------+
I used following query
update table set auto_no LIKE %'Y'- '????1'% where auto_no_new > 20577
But didn't get the desired output. What may be going wrong ? Can anyone help ?
Seems trivial
drop table if exists t;
create table t(auto_no varchar(12), auto_no_new int);
insert into t values
( '2021-10431' , 20577 ),
( '2021-10432' , 20578 ),
( '2021-10433' , 20579 ),
( '2021-10434' , 20580 ),
( '2021-10435' , 20581 ),
( '2021-10436' , 20582 );
update t
set auto_no = concat(substring_index(auto_no,'-',1),'-',lpad(auto_no_new - 20576,5,'0'))
where substring_index(auto_no,'-',1) = 2021;
select * from t;
+------------+-------------+
| auto_no | auto_no_new |
+------------+-------------+
| 2021-00001 | 20577 |
| 2021-00002 | 20578 |
| 2021-00003 | 20579 |
| 2021-00004 | 20580 |
| 2021-00005 | 20581 |
| 2021-00006 | 20582 |
+------------+-------------+
6 rows in set (0.013 sec)
or if you don't know the min(auto_no_new)
update t cross join(select min(auto_no_new) - 1 minno from t where substring_index(auto_no,'-',1) = 2021) s
set auto_no = concat(substring_index(auto_no,'-',1),'-',lpad(auto_no_new - s.minno,5,'0'))
where substring_index(auto_no,'-',1) = 2021;
After doing a few tests, this is what I come up with:
UPDATE table1 CROSS JOIN (SELECT #rn := 0) R
SET auto_no=CONCAT(SUBSTRING(auto_no,1,LOCATE('-',auto_no)),LPAD(#rn := #rn+1,5,0))
WHERE auto_no LIKE '2021-%';
However, I advise you to please don't run the update query without backing up your table first. I think the best way is for you to create a copy of the original table and run the update query over it rather than doing it on the original table. At least that would give you chance to do-over if something went wrong. Also, once you're satisfied with the end result (after the update), you can simply rename the original table to something like table1_original then rename the copy table as the original table.
Here is a fiddle demo
I am new to mysql and tried to research it but couldn't find any solution. I have a table like this:
| SW_Pair1 | SW_Pair2 | Pair1_VLAN1| Pair1_VLAN2| Pair2_VLAN1| Pair2_VLAN2| Inter | Mgmt| OSPF| Env | Domain|
|-----------------|-----------------|------------|------------|------------|------------|-------|-----|-----|-----|-------|
| Switch1.abc.com | Switch2.abc.com | VLAN-111 | VLAN-333 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch2.abc.com | Switch1.abc.com | VLAN-222 | VLAN-444 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch3.abc.com | Switch4.abc.com | VLAN-121 | VLAN-123 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch4.abc.com | Switch3.abc.com | VLAN-515 | VLAN-717 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch5.abc.com | Switch6.abc.com | VLAN-919 | VLAN-101 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch6.abc.com | Switch5.abc.com | VLAN-105 | VLAN-108 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch7.abc.com | Switch8.abc.com | VLAN-110 | VLAN-115 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
| Switch8.abc.com | Switch7.abc.com | VLAN-199 | VLAN-200 | Unknown | Unknown | 47 | 24 | 0.1 | Dev | abc |
Lets take first 2 rows as an example.
SW_Pair1 in row 1 == SW_Pair2 in row 2
SW_Pair1 in row 2 == SW_Pair2 in row 1
I put them in next row but they can be anywhere in database. Now I would like to merge these 2 so that data in Pair1_VLAN1 and Pair1_VLAN2 in row 2 goes in Pair2_VLAN1 and Pair2_VLAN2 of row 1 and then row 2 disappears. So, here is how the table should look after merge:
| SW_Pair1 | SW_Pair2 | Pair1_VLAN1| Pair1_VLAN2| Pair2_VLAN1| Pair2_VLAN2| Inter | Mgmt| OSPF| Env | Domain|
|-----------------|-----------------|------------|------------|------------|------------|-------|-----|-----|-----|-------|
| Switch1.abc.com | Switch2.abc.com | VLAN-111 | VLAN-333 | VLAN-222 | VLAN-444 | 47 | 24 | 0.1 | Dev | abc |
| Switch3.abc.com | Switch4.abc.com | VLAN-121 | VLAN-123 | VLAN-515 | VLAN-717 | 47 | 24 | 0.1 | Dev | abc |
and so on ..
I am using python 2.7 to push data to sql.
Edit:
I tried below query to add additional checks on DELETE but it failed:
UPDATE yourTable AS a
DELETE FROM yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1
WHERE Pair2_VLAN1 IS Unknown;
Or better, can it SET the values of Pair1_VLAN1 and Pair1_VLAN2 rows of second switch after it moves it data to switch 1? Maybe over-write the vlan to something like "MERGED". I can then safely remove anything that has "MERGED" in Pair1_VLAN1 and Pair1_VLAN2. I know it will only say that when it's data was successfully got moved to another row.
EDIT2:
nvm .. figured it out. See below:
UPDATE yourTable AS a
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1
SET a.Pair2_VLAN1 = b.Pair1_VLAN1,
a.Pair2_VLAN2 = b.Pair1_VLAN2,
b.Pair1_VLAN1 = "MERGED",
b.Pair1_VLAN2 = "MERGED
WHERE a.SW_Pair1 < a.SW_Pair2;
First update the first row in each pair with the data from the matching row:
UPDATE yourTable AS a
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1
SET a.Pair2_VLAN1 = b.Pair1_VLAN1,
a.Pair2_VLAN2 = b.Pair1_VLAN2
WHERE a.SW_Pair1 < a.SW_Pair2;
The WHERE clause ensures that only one row in each pair (the one with the lower name in SW_Pair1) is updated.
Then delete the rows that weren't updated. They will still have NULL in the columns that were updated by the first query.
DELETE FROM yourTable
WHERE Pair2_VLAN1 IS NULL;
This assumes that there are matching rows for everything. If you need something safer, you'll need to do a join that checks that there's a matching row with the opposite names.
DELETE a FROM yourTable AS a
JOIN yourTable AS b ON a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2 = b.SW_Pair1
WHERE a.Pair2_VLAN1 IS NULL
I'm sure there is a cleaner way to do this, but this is a hacky way I came up with.
select
a.sw_pair1,
a.sw_pair2,
a.pair1_vlan1,
a.pair2_vlan1 as pair1_vlan2,
b.pair1_vlan1 as pair2_vlan1,
b.pair2_vlan1 as pair2_vlan2
from TABLENAME a
join TABLENAME b on a.sw_pair1 = b.sw_pair2
where cast(substring_index(substring_index(a.sw_pair1, '.abc.com', 1), 'Switch', -1) as unsigned) % 2 > 0
I'm using the modulo (% 2) to make sure we get the odd numbers in the first column only, therefore having the even numbers in column 2. I'd be curious to see if someone else can come up with a cleaner solution for that than I did. If so, that would help me with some of the things I do from time to time.
This method worked for me and seems simpler than the current answers. This gave your desired output from the sample data.
SELECT
a.SW_Pair1,
a.SW_Pair2,
a.Pair1_VLAN1,
a.Pair1_VLAN2,
b.Pair1_VLAN1 as Pair2_VLAN1,
b.Pair1_VLAN2 as Pair2_VLAN2
FROM test as a , test as b
WHERE a.SW_Pair1 = b.SW_Pair2 AND a.SW_Pair2>b.SW_Pair2;
If you want to store the merged data into table, then #Barmar's solution will work perfectly.
But if you just want to display the data then following query will get the job done:
select least(t1.SW_Pair1,t1.SW_Pair2),greatest(t1.SW_Pair1,t1.SW_Pair2),
t2.Pair1_VLAN1,t2.Pair1_VLAN2,
t1.Pair1_VLAN1 as Pair2_VLAN1,t1.Pair1_VLAN2 as Pair2_VLAN2
from tablet1 as t1
inner join tablet2 as t2
on t2.SW_Pair1 = t1.SW_Pair2 and t2.SW_Pair2=t1.SW_Pair1
group by least(t1.SW_Pair11,t1.SW_Pair2),greatest(t1.SW_Pair1,t1.SW_Pair2);
Hope it helps!
+----+------------+------------+------------+----------+
| id | phone_no | join_date | city | blood_gp |
+----+------------+------------+------------+----------+
| 1 | 80077672xx | 1997-07-19 | Delhi | NULL |
| 2 | 80077642xx | 1998-07-19 | New Delhi | NULL |
| 3 | 80477642xx | 1999-07-19 | Mumbai | NULL |
| 4 | 80077654xx | 1997-05-31 | Kolkata | NULL |
+----+------------+------------+------------+----------+
I want to enter all the blood groups at once . Is there a way to do so ?
you can use single query with select and update
UPDATE table1 , (SELECT * FROM table2 where 1) src
SET table1.blood_gp = src.filed2 where 1 ;
if you want to insert multiple row data using single query then use this code
INSERT INTO yourtable (x,y,z) VALUES (a1,a2,a3), (b1,b2,b3);
or if you want to update one column value all filed then use this code
update yourtable set blood_gp = 'yourvalue' where 1;
if any problem then inform me
Just make an update query without where clause.
update table set blood_gp = 'value'
That's generalize query.
I want to select value from table sorted by a certain order.
I have a table called test that looks like this:
| date | code | value |
+----------+-----------+----------+
| 20050104 | 000005.SZ | -6359.19 |
| 20050104 | 600601.SH | -7876.34 |
| 20050104 | 600602.SH | -25693.3 |
| 20050104 | 600651.SH | NULL |
| 20050104 | 600652.SH | -15309.9 |
...
| 20050105 | 000005.SZ | -4276.28 |
| 20050105 | 600601.SH | -3214.56 |
...
| 20170405 | 000005.SZ | 23978.13 |
| 20170405 | 600601.SH | 32212.54 |
Right now I want to select only one date, say date = 20050104, and then sort the data by a certain order (the order that each stock was listed in the stock market).
I have another table called stock_code which stores the correct order:
+---------+-----------+
| code_id | code |
+---------+-----------+
| 1 | 000002.SZ |
| 2 | 000004.SZ |
| 3 | 600656.SH |
| 4 | 600651.SH |
| 5 | 600652.SH |
| 6 | 600653.SH |
| 7 | 600654.SH |
| 8 | 600602.SH |
| 9 | 600601.SH |
| 10 | 000005.SZ |
...
I want to sorted the selected data by stock_code(code_id), but I don't want to use join because it takes too much time. Any thoughts?
I tried to use field but it gives me an error, please tell me how to correct it or give me an even better idea.
select * from test
where date = 20050104 and code in (select code from stock_code order by code)
order by field(code, (select code from stock_code order by code));
Error Code: 1242. Subquery returns more than 1 row
You told us that you don't want to join because it takes too much time, but the following join query is probably the best option here:
SELECT t.*
FROM test t
INNER JOIN stock_code sc
ON t.code = sc.code
WHERE t.date = '20050104'
ORDER BY sc.code_id
If this really runs slowly, then you should check to make sure you have indices setup on the appropriate columns. In this case, indices on the code columns from both tables as well as an index on test.date should be very helpful.
ALTER TABLE test ADD INDEX code_idx (code)
ALTER TABLE test ADD INDEX date_idx (date)
ALTER TABLE code ADD INDEX code_idx (code)
I have a table of locations that are verified, like so:
+--------+----------+----------+
| idW | lat | lon |
+--------+----------+----------+
| 111650 | 47.20000 | 14.75000 |
| 111810 | 47.96412 | 16.25498 |
| 111820 | 47.83234 | 16.23143 |
+--------+----------+----------+
I also have a table of "all locations", whether verified or not. It looks like this (with lots of other columns I'm leaving out)
+--------+--------+----------+----------+
| id | idW | lat | lon |
+--------+--------+----------+----------+
| 100000 | 111650 | 47.20000 | 14.75000 |
| 100001 | 111712 | 42.96412 | 19.25498 |
| 100002 | 111820 | 47.83234 | 16.23143 |
+--------+--------+----------+----------+
What I would like to do is, for each verified location, find its "id" in the table of "all locations", and attach those as a new first column on the verified table (remembering that not all verified locations exist in all locations, so it's not as easy as copy and paste I don't think). Any ideas?
edit: The expected output from my example above would be
+--------+--------+----------+----------+
| id | idW | lat | lon |
+--------+--------+----------+----------+
| 100000 | 111650 | 47.20000 | 14.75000 |
| 100002 | 111820 | 47.83234 | 16.23143 |
| x | 111810 | 47.96412 | 16.25498 |
+--------+--------+----------+----------+
where x would be whatever value that 111810 had as its id in the all locations table.
The better option would be to only display the additional data when you query the database using in joins either in a normal query or in a view.
select t1.*, t2.field1, t2.field2 from t1 inner join t2 on t1.idW=t2.idW
You can copy the data over to your 1st table (there are valid reasons to do it, eg. optimalization of selects, but itás a rare case). You need to add the extra columns to your first table using alter table add column ... commands (or just use an sql editor app).
Then to copy the data over:
update t1, t2 set t1.fieldname=t2.fieldname where t1.idW=t2.idW
Since adding columns to a table is not really efficient, you may choose to create a 3rd table from the existing ones and copy the data over:
create table t3 as select t1.*, t2.fieldname1, t2.fieldname2
from t1 inner join t2 on t1.idW=t2.idW
If I understand correctly you want to add a new column to your original table. This can be done as
ALTER TABLE locations ADD COLUMN `id` INTEGER NULL DEFAULT NULL FIRST;
and afterwards you can populate it by getting the values from the verified locations table as
SET SQL_SAFE_UPDATES = 0;
UPDATE locations a SET id =
(SELECT id FROM verified_locations b
WHERE a.idW = b.idW AND a.lat = b.lat AND a.`long` = B.`long`
LIMIT 1);