MySQL output most visited locations - mysql

I've got a table in a MySQL-database with thousands of checkins from my phone. Every x seconds, a new location is inserted.
This is how the table looks like:
+----+-----------+----------+------------+------------+
| id | lat | lon | date | timestamp |
+----+-----------+----------+------------+------------+
| 1 | 51.650586 | 5.622935 | 14-08-2018 | 1534233062 |
+----+-----------+----------+------------+------------+
| 2 | 51.65181 | 5.622228 | 14-08-2018 | 1534230962 |
+----+-----------+----------+------------+------------+
| 3 | 51.653715 | 5.6194 | 14-08-2018 | 1534230121 |
+----+-----------+----------+------------+------------+
Besides the GPS coordinates, date and timestamp I'm saving address data from the Google Maps Geocode API too, but street names aren't always right so it's not useful to use for data grouping.
I'm currently displaying the last inserted location on a Google Map using JavaScript, just as a single pointer. I'm looking for a MySQL-query that outputs a list of the 5 most visited locations for a defined date. There are a few hundred location check-ins a day.
It would be great if they could be grouped together, with a distance set of 500 meters. So for example, the 3 locations from above will be grouped together as the distance between them is less than 500 meters.
Could somebody help me writing a query for this? All help is highly appreciated.

Related

Selecting MySQL data rows with an int range

Alright, for starters I am not very experienced with mysql.
The situation is as following:
I have a data table with zip code records. I need a query that finds the correct row with a zip code and number, where the table has a number range, something like this.
Zipcode | NumberLower | NumberUpper | Street name
1234AB | 10 | 20 | Imaginary Drive
1234AB | 30 | 40 | Fantasy Street
7261XY | 2 | 4 | Rainbow Road
My current query is
SELECT * FROM zipcodetable WHERE zipcode="1234AB"
which returns the first two rows, as expected. What query should I use if I want to find the street name for the adress with zipcode 1234AB and number 34?
Add BETWEEN clause:
SELECT *
FROM zipcodetable
WHERE Zipcode='1234AB'
AND 34 BETWEEN NumberLower AND NumberUpper

Grafana worldmap panel: latitude and longitude in mysql cannot display points on map

I am using a worldmap panel on Grafana v5.4.2, my data source is a mysql database, and there I have some ip address, city and location string with latitude and longitude, I would like to display the city name of the ip addresses, the value would be the ip address count belongs to a city, the following is my sql:
SELECT
any_value(city.city) as metric,
count(ip.loc) as value,
CAST(substring(ip.loc, 1, INSTR(ip.loc, “,”) - 1) AS DECIMAL(10,6)) as latitude,
CAST(substring(ip.loc, INSTR(ip.loc, “,”) + 1) AS DECIMAL(10,6)) as longitude,
UNIX_TIMESTAMP(now()) as time_sec
FROM ip
inner join city on city.ctid = ip.ctid
WHERE ip.iptype & 2
group by ip.loc
I can get response with the sql query, the response is something like the following, but nothing display on the map:
xhrStatus:“complete”
request:Object
method:“POST”
url:“api/tsdb/query”
data:Object
from:“1541896435220”
to:“1547534884686”
queries:Array[1]
response:Object
results:Object
A:Object
refId:“A”
meta:Object
series:Array[516]
0:Object
1:Object
2:Object
3:Object
name:“巴西 巴西 value”
points:Array[1]
0:Array[1,1547534884000]
4:Object
5:Object
6:Object
7:Object
…
the following is the ruling result from mysql:
±--------±-------±----------±-----------±----------+
| metric | value | latitude | longitude | time_sec |
±--------±-------±----------±-----------±----------+
| 巴西 巴西 | 1 | -14.242900 | -54.387798 | 1547535460 |
| 巴西 圣保罗州 圣保罗 | 1 | -23.550520 | -46.633309 | 1547535460 |
| 新加坡 新加坡 | 16 | 1.352083 | 103.819836 | 1547535460 |
| 越南 越南 | 1 | 10.768451 | 106.694363 | 1547535460 |
| 柬埔寨 柬埔寨 | 7 | 12.547730 | 104.983856 | 1547535460 |
…
can anyone address me what’s going on?
your contribution helped me with WorldMap.
and I will try to help you with your problem (Unfortunately, it is still not perfect as there is "n/a" display when mouse hit the points).
First: My sourcedata from Postgresql. I have one tables where i keep coordinates
Coordinates Table
Second: My sql query is:
SQL query and result from query: result
Third: My worldmap Settings
worldmap settings
FINALe: Working worldmap
REsULT
After changing the "Format as" to "Table", and remove the "metric" from my sql, it prints point on the map.
Unfortunately, it is still not perfect as there is "n/a" display when mouse hit the points, I expecting something like city name, that's why I put the city as metric...need more investigation...

Using an SQL View to dynamically place field data in buckets

I have a complex(?) SQL query I am needing to build. We have an application that captures a simple data set for multiple clients:
ClientID | AttributeName | AttributeValue | TimeReceived
----------------------------------------------------------------
002 | att1 | 123.98 | 23:02:00 02-03-20017
----------------------------------------------------------------
003 | att2 | 987.2 | 23:02:00 02-03-20017
I need to be able to return a single record per client that looks something like this
Attribute | Hour_1 | Hour_2 | Hour_x |
--------------------------------------
att1 120.67 |
--------------------------------------
att2 | 10 | 89.3 |
The hours are to be determined by a time provided to the query. If the time was 11:00 on 02-03-20017, then hour 1 would be from 10-11 on 02-03-20017, and hour 2 from 9-10 on 02-03-20017. Attributes will be allocated to these hourly buckets based on the hour/date in their time stamp (not all buckets will have data). There will be a limit on the number of hours allocated in a single query. In summary, there are possibly 200-300 attributes and hourly blocks of up to 172 hours. To be honest I am not really sure where to start to build a query like this. Any guidance appreciated.

use st_within to get the locations in a radius/circle

I have a table that looks like this
| id | name | latitude | langitude | costLat | sinLat | cosLng | sinLng |
| 1 | place 1 | 2.942743912327621 | 101.79377630352974 | 0.99868133582304 | 0.051337992546461 | -0.20438972214917 | 0.97888959616485 |
Referring to this article, it seems like a good idea to use st_within in order for me to search for locations within 5 km radius from a given latitute and langitude in my table above. But I totally have no idea how to do that.
The table is MyISAM, MySQL version 5.6
Sorry for not being clear on what I tried. From the documentation it mentions that
ST_Within(g1,g2)
Returns 1 or 0 to indicate whether g1 is spatially within g2.
So my understanding is, we need to pass 2 params to ST_Within. Sound simple enough, but when I looked at the sample query in the linked articles, it does (*note: I changed shape to CIRCLE in the query, as my assumption is my shape is CIRCLE because I'm searching for radius)
set #lat= 37.615223;
set #lon = -122.389979;
set #dist = 10;
set #rlon1 = #lon-#dist/abs(cos(radians(#lat))*69);
set #rlon2 = #lon+#dist/abs(cos(radians(#lat))*69);
set #rlat1 = #lat-(#dist/69);
set #rlat2 = #lat+(#dist/69);
SELECT ASTEXT("CIRCLE"), NAME FROM location_final
WHERE st_within("CIRCLE", ENVELOPE(LINESTRING(POINT(#rlon1, #rlat1), POINT(#rlon2, #rlat2))))
ORDER BY st_distance(POINT(#lon, #lat), "CIRCLE") LIMIT 10;
So looking at the query above, my confusion is, where do the comparison between the latitude and langitude happens? Where in the query should I mention about my column latitude and langitude?
Looking at the output at the given link, it display something like
+--------------------------------+-------------------------------+
| astext(shape) | name |
+--------------------------------+-------------------------------+
| POINT(-122.3890954 37.6145378) | Tram stop:Terminal A |
| POINT(-122.3899 37.6165902) | Tram stop:Terminal G |
Where do the POINT come from?

How to store all geographical locations around the world in Database?

I am working for a travel site, where i need to store the tourist spots which tourists traveled to. I need the spots to be unique in the locations table so that i can know the popularity of a particular spot etc.
I will also need also need all countries, states, cities stored with me because i cannot depend on user input.
The database is MySQL.
Seeing the data sets available for such locations i see there is a problem of nesting of cities across countries which may use provinces, states, counties etc.
So, my question is how to design the schema so that i can store all the locations.
I was thinking about having tables for countries, states, cities, and spots.
the spots table will contain spot_name, cityId, stateId, countryId, and some fields to have longitude and latitude bounds.
This way i can identify same spots by their geopositions.
But again, this solution won't work because of the states/provinces/counties etc. problem.
Can you please suggest how to build the schema and go about seeding it with correct data so that dependency on user input is minimum.
you should use a geospatial database as then you can store your locations like countries and states as spatial entities and so can determine the nesting correctly.
If you can't use one you can simulate geospatial positions using strings in a normal table by dividing the world up into a grid, then subdividing each square of the grid recursively.
For example divide the world into 9 squares, numbered 1-9 from top left to bottom right. Anything which is in these large squares has only a single digit reference. Then divide each square into 9 and anything which is at this level has a 2 digit reference. so 11 is the top left square and 99 is the bottom right square.
Repeat this process until you have the precision that you need. a single feature might have a reference 10 digits long 5624357899 but you would know that this would be inside any larger feature which is fewer digits which starts with the same string like 5624357. So your countries would have fewer digits because they are larger, but your individual locations would have more because they are smaller and more accurately located.
This will only give you a course approximation of location (and will be bad for long thin features) but might be suitable enough
The first grid will look like this:
______________________________
| | | |
| 1 | 2 | 3 |
| | | |
|_________|_________|_________|
| | | |
| 4 | 5 | 6 |
| | | |
|_________|_________|_________|
| | | |
| 7 | 8 | 9 |
| | | |
|_________|_________|_________|
The second round looks like this (only first square completed for simplicity):
______________________________
|11|12 |13| | |
|---------| 2 | 3 |
|14|15 |16| | |
|---------| | |
|17|18 |19| | |
|_________|_________|_________|
| | | |
| 4 | 5 | 6 |
| | | |
|_________|_________|_________|
| | | |
| 7 | 8 | 9 |
| | | |
|_________|_________|_________|
you repeat this process until you have fine enough approximation for your purposes.
I think the schema part of your problem would be pretty simple. But the real problem is how you would get the data for your user to select - you are imagining the (almost) impossible! I don't think there is any database in existence which would translate a co-ordinate to a place name. Even Google can't (yet) do that for you - for example, a search for "Lat Long Taj Mahal" provides 27.1750, 78.0419 (Google have used their own and other people's experience to tell you that); but a search for "27.1750, 78.0419" just yields a pin on the map, and then our human eyes can see that the pin is 'pretty close' to a place named "Taj Mahal" (or ताज महल in Hindi, or તાજ મહેલ in Gujarati )...
Just imagine - how you would populate your schema? Think about how many co-ordinates you would need in your table if you wanted decent accuracy (needing at least 6 decimal places)! And who would be the authority on place names?
So I think your best approach might be to:
Use the publically available lists of country/city names translated
to their co-ordinates,
Build your app so it pre-populates the closest co-ordinate to the user's
precise location, and then
Allow the user to qualify the match with their own (more
specific) chosen place name.
Then YOU could store the precise co-ordinate gathered by your app, along with the place name the user specified; and sell the data for $millions! (I suspect Google are already doing this ;)