Getting the closest locations based on Latitude / Longitude
I'm not going to explain what is being done here (SQL script) because I just don't understand. I searched a long time for this script and at the moment i'm not even sure where I got it... bottomline.. it works, and really really good.
Let's say you got the lat/lng from an http call to the Google API (small example below) and you want to get the nearest 10 other "stores" in the area around you.
<cfhttp url="http://maps.google.com/maps/geo?q=#yourpostcode-address#&gl=nl&output=csv&sensor=false&key=#yourGooglekey#" method="GET" />
<cfset aRet = listToArray(cfhttp.filecontent) />
<!--- Is it a good request and is the accuracy more then 5 (postcode level) --->
<cfif aRet[1] eq 200>
-- call the stored procedure
EXEC getstores @lat = #aRet[3]#
,@lng = #aRet[4]#
</cfif>
<!-- Save procedure in your database MSSQL 2000 and up. -->
CREATE PROCEDURE [dbo].[getstores] @lat float, @lng float AS
DECLARE @radius float, @DegToRad float
SET @DegToRad = 57.29577951
SET @radius = 25000
SELECT TOP 10
sto_city
,sto_name
,sto_lat
,sto_lng
,sto_street
,sto_postcode
,sto_tel
,sto_fax
,sto_email
,sto_url
,sto_supplier
,sto_cnt_code
,ROUND((ACOS((SIN(@lat/57.2958) * SIN(sto_lat/@DegToRad)) +(COS(@lat/@DegToRad) * COS(sto_lat/@DegToRad) *COS(sto_lng/@DegToRad - @lng/@DegToRad))))* 6387.7, 2) AS distance
FROM store
WHERE (sto_lat >= @lat - (@radius/111))
And (sto_lat <= @lat + (@radius/111))
AND (sto_lng >= @lng - (@radius/111))
AND (sto_lng <= @lng + (@radius/111))
AND (
ISNUMERIC(sto_lat) = 1
AND
ISNUMERIC(sto_lat) = 1
)
ORDER BY distanceThe distance column from the stored procedure is the total distance from the location you submitted to the Google API (postcode / address). Hope you can find a good use for this.. I did for several projects already :-)
7190 viewed | 4 opinion(s) | Tjarko @ 23:43 cet
How to Remove, Delete double records but still have the values intact.
First we get all the double records. In this case I have a table called "test" with 2 columns "tst_id char(26) DEFAULT newid(),tst_name varchar(50)".
Secondly we use the GROUP attribute in the <cfquery> tag to only get SINGLE records. In this query we declare a temporary table (MSSQL - memory only) and we insert the SINGLE records in that table
then we DELETE all the double items and after that insert all the single items back into the original table from the temporary table.
Leaves you with all the double items removed!! BUT BE CAREFULL, this method doesn't take into account that records may have a relation with other tables in the database...
<cfquery>
SELECT tst_id,tst_name
FROM test
WHERE UPPER(tst_name) IN (
SELECT UPPER(tst_name) as tst_name
FROM test
GROUP BY tst_name
HAVING (COUNT(UPPER(tst_name)) > 1)
)
ORDER BY tst_name
</cfquery>
<cfsavecontent variable="sqlStmt">
DECLARE @tmp TABLE (tst_id char(36),tst_name varchar(50))
<!--- Only insert single items of the double records --->
<cfoutput query="qDouble" group="tst_name">
INSERT INTO @tmp VALUES ('#tst_id#','#tst_name#')
</cfoutput>
<!--- Delete ALL double records --->
DELETE
FROM test
WHERE UPPER(tst_name) IN (
SELECT UPPER(tst_name) as tst_name
FROM test
GROUP BY tst_name
HAVING (COUNT(UPPER(tst_name)) > 1)
)
<!--- Insert the single records back in the database --->
INSERT INTO test (tst_id,tst_name)
SELECT tst_id,tst_name FROM @tmp
</cfsavecontent>
<!--- Execute the query --->
<cfquery>
#PreserveSingleQuotes(sqlStmt)#
</cfquery>
10840 viewed | 2 opinion(s) | Tjarko @ 10:07 cet
How to find duplicate values in a table?
With the SQL statement below you can find duplicate values in any table, just change the tablefield into the column you want to search and change the table into the name of the table you need to search.
In your recordset you will see the tablefield and how many times it is found as a duplicate.
SELECT tablefield, COUNT(tablefield) AS dup_count
FROM table
GROUP BY tablefield
HAVING (COUNT(tablefield) > 1)
Some further tempering with the statement gets the complete records that are double. (yeah yeah.. no * should be used in the SELECT) It's just for demonstrating folks!!
SELECT *
FROM table
WHERE tablefield IN (
SELECT tablefield
FROM table
GROUP BY tablefield
HAVING (COUNT(tablefield ) > 1)
)
To go even further in the process and DELETE every double record we could do something like make a temporary table, insert the double records, delete it from the original table and insert the saved single records from the temporary table.
186789 viewed | 29 opinion(s) | Tjarko @ 23:56 cet
How do I randomly show a query record?
The easiest way to do this is by the "ORDER BY newid()" statement within your SQL statement. Drawback is that you need SQL server with this.
SELECT TOP 1 *
FROM table
ORDER BY newid()
The query above will give you a randomly choosen record each time.
Another way of doing this is by randomly displaying a record from the queryset you have.. you can do that like this (if you use access or some other database)
<cfquery name="rs" datasource="#dsn#">
SELECT *
FROM table
</cfquery>
<cfset displayRow = randRange(1,rs.recordcount)>
<cfoutput query="rs" startrow="#displayRow#" maxrows="1">
-- show your record
</cfoutput>
13098 viewed | 5 opinion(s) | Tjarko @ 10:06 cet
Insert with a select
Sometimes you need to update a table from another table and what you can do then is SELECT all data.. loop over it with CF en INSERT the data into the other table....OR.... you can let the database sort it out.
INSERT INTO table1 (column1,column2,column3....)
SELECT column1,
column2,
'somevalue' AS column3,
....
FROM table2
6290 viewed | 2 opinion(s) | Tjarko @ 14:59 cet
Multiple conditions in JOIN statement
You can put multiple conditions in your LEFT, RIGHT and INNER/OUTER joins if you want.. below a small example that will give you the idea.
SELECT tbl.id, tblo.naam
FROM sometable tbl
LEFT JOIN someothertable tblo ON tblo.id = tbl.id
AND tblo.function = tbl.function
ORDER BY ....
Didn't know this one.. could have saved me a lotta query's in the past :-(
62325 viewed | 11 opinion(s) | Tjarko @ 0:00 cet