MySQL moving around strings, before and after comma - mysql

I have a mysql row that has coordinates saved in lat/long. I need it to be changed to long/lat.
I understand that this needs to be deliminated somehow and changed around.
What is the correct way to do this in MySQL?
Sample:
["26.247798956308,50.657465902192","26.247765257163,50.656210342278","26.24777327998,50.655413265762","26.247772343418,50.655399250007","26.24775833567,50.655206036067","26.247768008419,50.655097864672","26.247779429251,50.654965656351","26.247844499259,50.654613999694","26.247882692272,50.654350538671","26.247886070313,50.654253400286","26.248070301095,50.654265872269","26.24871145246,50.654291010692","26.248712355399,50.65429100802","26.248938997758,50.654292339968","26.248939900696,50.654292337296","26.249167443576,50.654292665245","26.249652369652,50.654311256915","26.24965327259,50.654311254243","26.250527203555,50.65426160469","26.251604232782,50.654185317821","26.251850689062,50.654165562357","26.252226248584,50.654138414997","26.252525072823,50.654117502871","26.252875354859,50.654092432768","26.253260873151,50.654076270464","26.253503640429,50.654024481477","26.253881809743,50.653956269108","26.253918794004,50.653941138898","26.253934151183,50.65394409752","26.254001887777,50.653956645335","26.254066915409,50.653981134594","26.254127534099,50.654016927469","26.254182158719,50.654063086371","26.254229361508,50.654118404871","26.254267909164,50.654181436626","26.254426530564,50.654433314626","26.254430159178,50.654440313548","26.254140446036,50.654870761592","26.253604791621,50.655536254578","26.253060504139,50.655991479569","26.252712653207,50.656277893161","26.252469279111,50.656453847903","26.252138350894,50.65664307698","26.25144296537,50.656971562628","26.250888157852,50.657182473989","26.250417074844,50.657288997819","26.249898133586,50.657394659791","26.248058102136,50.657466143684","26.247798956308,50.657465902192"]

A general rule (it is called DB normalization) is:
Never store multiple values in a single column!
So if you can change your table design you can do it like this (in my example we store points of user favorites - I don't know what purpose your points have):
users table
-----------
id
name
....
coordinates table
-----------------
user_id
lng
lat
If you then want to retrieve all records of user 'Tom' then you can run this query
select c.lng, c.lat
from coordinates c
join users u on u.id = c.user_id
where u.name = 'Tom'

If your row has a field containing a list of comma separated lat/long pairs, then would be better to have long/lat stored as separate fields in a new table with foreign key referencing the original table. Even better would be to use a Point field as suggested by #a_horse_with_no_name instead of lat/long separate fields.

Related

How to select comma-separated values from a field in one table joined to another table with a specific where condition?

I'm working on a mysql database select and cannot find a solution for this tricky problem.
There's one table "words" with id and names of objects (in this case possible objects in a picture).
words
ID object
house
tree
car
…
In the other table "pictures" all the information to a picture is saved. Besides to information to resolution, etc. there are especially informations on the objects in the picture. They are saved in the column objects by the ids from the table words like 1,5,122,345, etc.
Also the table pictures has a column "location", where the id of the place is written, where I took the picture.
pictures
location objectsinpicture ...
1 - 1,2,3,4
2 - 1,5,122,34
1 - 50,122,345
1 - 91,35,122,345
2 - 1,14,32
1 - 1,5,122,345
To tag new pictures of a particular place I want to become suggestions of already saved information. So I can create buttons in php to update the database instead of using a dropdown with multiple select.
What I have tried so far is the following:
SELECT words.id, words.object
FROM words, pictures
WHERE location = 2 AND FIND_IN_SET(words.id, pictures.objectsinpicture)
GROUP BY words.id
ORDER BY words.id
This nearly shows the expected values. But some information is missing. It doesn't show all the possible objects and I cannot find any reason for this.
What I want is for example all ids fo location 2 joined to the table words and to group double entries of objectsinpicture:
1,5,122,34
1,14,32
1,5,14,32,34,122
house
...
...
...
...
...
Maybe I need to use group_concat with comma separator. But this doesn't work, either. The problem seems to be where condition with the location.
I hope that anyone has an idea of solving this request.
Thanks in advance for any support!!!
This is a classic problem of denormalization causing problems.
What you need to do is store each object/picture association separately, in another table:
create table objectsinpicture (
picture_id int,
object_id int,
primary key (picture_id, object_id)
);
Instead of storing a comma-separated list, you would store one association per row in this table. It will grow to a large number of rows of course, but each row is just a pair of id's so the total size won't be too great.
Then you can query:
SELECT w.id, w.object
FROM pictures AS p
JOIN objectsinpicture AS o ON o.picture_id = p.id
JOIN words AS w ON o.object_id = w.id
WHERE p.location = 2;

SQL Query - c# database connection (DataGrid)

I'm trying to get information from 2 tables with a SQL query..
SELECT Num_of_icon, ID_Radar, ID_Observer,
Longitude_Impact_point, Latitude_Impact_point,
Longitude_Impact_point_By_Cutting, Latitude_Impact_point_By_Cutting,
Deviation_In_Meters,
Longitude_Deviation, Latitude_Deviation,
Longitude, Latitude, Azimuth
FROM ShowTable, Observer
ORDER BY Num_of_icon ASC
Num_of_icon is a key in one table.
ID_Observer is a key in the second table and a field in the first table.
The error is:
The field 'ID_Observer' should be show in more than one table.
I dont understand what this error is about.. I know that ID_Observer is showing more than one table, that's why I have a connection between the tables...
You have to qualify a column with tablename.columnname if a column exists in two tables. You also have to link both tables via JOIN:
SELECT Num_of_icon,
ID_Radar,
SHowTable.ID_Observer, --<<< HERE
Longitude_Impact_point,
Latitude_Impact_point,
Longitude_Impact_point_By_Cutting,
Latitude_Impact_point_By_Cutting,
Deviation_In_Meters,
Longitude_Deviation,
Latitude_Deviation,
Longitude,
Latitude,
Azimuth
FROM ShowTable
INNER JOIN Observer
ON ShowTabl.ID_Observer = Observer.ID_Observer --<<< and HERE
ORDER BY Num_of_icon ASC
The query processor does not know which of the ID_Observer fields it should take (and it doesn't make an effort to determine whether they will always be the same value regardless of which table it takes it from). So you'll have to specify this, ie the following will take the ID_Observer value from the Observer table:
"SELECT Num_of_icon,ID_Radar,Observer.ID_Observer,Longitude_Impact_point..."

Update table based on other 2 related tables

I have a strange problem. I got some data for cities, regions and countries in CSV format and imported them into MySQL tables.
I have 3 tables and their fields
1. City : id, name, country_code, region_number
2. Region : region_number, country_code, name
3. Country : country_code, name
Now things get a little complicated, as I added an auto-generated id column to the region table, so the region x for country y would be unique.
The thing is: Now i am trying to update city field region_number to hold this unique value (the new id column in region) so I can have relations city->region.
The relation region->country or country->region is OK.
Is it possible to write an update query that would update city region_code (or fill some new column, eg. region_id) with correct values?
If not an query, what could I use to get the correct values into the cities table?
I have arround 3 million records!
If I understant correctly, I think you are looking for something like this:
UPDATE
City inner join Region
on City.country_code = Region.country_code
and City.region_number = Region.region_number
SET
City.new_column = Region.id
However, since there's a relation already between City and Region, I am not sure this is the right thing to do, since it will make the table not normalized.
Now i am trying to update city field region_number to not hold this unique value
The only way you can do this is if the region_number uniquely identifies each region - and if that's already the case then you are wasting your time by creating redundant references. Although frankly, if these really are your table structures, there's no reason for using surrogate keys. And if there's no reason for using surrogate keys then the region and country table are redundant.

mysql SELECT IN followed by comma separated field

I use mySQL and I have a members table with a BLOB 'contacts' field containing a comma separated list of other member's IDs:
TABLE members:
id_member = 1
firstname = 'John'
contacts (BLOB) = '4,6,7,2,5'
I want to retrieve all the first names in the 'contacts' list of an individual, with a single query. I tried the following:
SELECT firstname from members WHERE id_member IN ( SELECT contacts FROM members WHERE id_member = 1 );
It returns only one row, but when I try:
SELECT firstname from members WHERE id_member IN ( 4,6,7,2,5 );
It returns all the first names from the list. I can use two queries to achieve this, but I thought I'd double check if there's a way to make it work with one simple, elegant query.
Thanks for reading, any help appreciated.
Jul
That seems like a very poor table design. Is it possible to change it?
If you can't change the design then you can handle comma separated values in MySQL by using FIND_IN_SET but it won't be able to use indexes efficiently:
SELECT firstname
FROM members
WHERE FIND_IN_SET(id_member, (SELECT contacts FROM members WHERE id_member = 1))
But rather than going this route, I'd strongly recommend that if possible you normalize your database. Consider using a join table instead of a comma separated list. Then you can find the entries you need by using joins and the search will be able to use an index.
If you're using a serialized BLOB type column to store these values then you're not going to be able to do what you want. A more SQL friendly approach is to create a relationship table that can be used as part of a JOIN operation, such as a member_contacts table that has an association between one id_member value and some other.
Expanding your comma separated list into individual records is a pretty simple mechanical process.
Can you change this DB structure? The contacts field really should be a related table rather than a column. Assuming a contacts table with this structure:
id_contact
id_member
Then you would use EXISTS instead:
SELECT firstname from members m WHERE EXISTS (SELECT 1 FROM contacts c WHERE c.id_contact = m.id_member );

Multitable stores when other store locations are in sub-table

I have a database that allows a list of businesses.
The Master table has the customer aka businesses details:
id
firstname
lastname
tradingname
storeaddress
state
postcode
In a table called Otherstores, I have the following:
master_id
store_id
storeaddress
state
postcode
phonenumber
What I now need to do is a PHP script that allows me to show all the stores in a list function but here is the catch:
I only want to show 8 stores from different types of categories so they are random.
However I then need it NOT to show a store twice on the same search.
I need it to make the sub-stores aka Otherstores also be randomly added into the query so that they are seeable as well.
I wondering the best way to do this.
WHY I DON'T HAVE ANY CODE:
It's tough to show you code as my idea was to do a left join or INNER join and limit it to id 1.
However I know that won't work because I would need to be able to join them together some how, but I want each sub store to be like its a master store so if I join it to the master table I can't see that working, and instead you will just get errors.