sql hacks using mysql server 5.0 ralfe poisson

Post on 08-Jan-2018

224 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Retrieving SQL-Generated Data Some Usefule Static Functions in SQL mysql> SELECT CURRENT_USER, CURRENT_DATE, CURRENT_TIMESTAMP, VERSION(), RAND() ; Example | CURRENT_USER | CURRENT_DATE | CURRENT_TIMESTAMP | VERSION() | RAND() | | | | :56:09 | log | |

TRANSCRIPT

SQL Hacks

Using MySQL Server 5.0

Ralfe Poisson                                                                 http://www.ralfepoisson.com

Overview• Retrieving Structural Information

• Retrieving SQL-Generated Data

• Paging Output

• Calculating distance from GPS co-ordinates

• Generate All Possible Permutations

• Generate a Random Permutations

• Creating ASCII Graphs with pure SQL

• Creating a Calendar with pure SQL

• Google-Like Search Results

Retrieving SQL-Generated Data

Some Usefule Static Functions in SQL

mysql> SELECT    CURRENT_USER,                                CURRENT_DATE,                                CURRENT_TIMESTAMP,                                VERSION(),                                RAND() ;  Example 

+--------------+--------------+---------------------+------------+-----------------+| CURRENT_USER | CURRENT_DATE | CURRENT_TIMESTAMP   | VERSION()  | RAND()          |+--------------+--------------+---------------------+------------+-----------------+| ralfe@%      | 2008-11-25   | 2008-11-25 09:56:09 | 5.0.44-log | 0.5004263757732 |+--------------+--------------+---------------------+------------+-----------------+

Getting Structural Information

MySQL makes provision for simple output of structural information:

• Listing Databases SHOW DATABASES

• Listing Tables SHOW TABLES

• Table Structure DESCRIBE `tablename`

• Command Used to Create Table SHOW CREATE TABLE `tablename`

Paging Output

It is possible to page the output of a SQL command by specifying an external tool. This can be a standard UNIX tool, or a custom script. You may also pass parameters to the tool/script.

Example

mysql> pager less ;

Calculating Distance from GPS data.

If we have a table of GPS co-ordinates, we can calculate the distance between them.

Step 1

CREATE TABLE `gps` (    `name` varchar(255) NOT NULL default '',    `latitude` decimal(10,4) NOT NULL default 0,    `longitude` decimal(10,4) NOT NULL default 0,    PRIMARY KEY (`name`));

INSERT INTO `gps` VALUES ('Cybertek', 31.002010, -29.492991);INSERT INTO `gps` VALUES ('Pavilion', 30.560729, -29.505736);INSERT INTO `gps` VALUES ('Sydney', 151.133607, -33.514144);

Calculating Distance from GPS data

Step 2

Once we have set up our GPS co-oridnates in a table, we need to convert them to radians and store the Earth's radius as a constant. To do this we use a View:

CREATE VIEW `gps_rad` AS    SELECT         `name`, 3.14159265359 * `latitude` / 180 as 'lat',        3.14159265359 * `longitude` / 180 as 'lon',        6378 as 'R'    FROM `gps`;

Calculating Distance from GPS data

Step 3

Using our friend, the Pytagorean Theorem, we can calculate the distance in kilometers..... MAGIC.

SELECT SQRT(dx * dx + dy * dy)    FROM (        SELECT             p1.R * (p2.lon - p1.lon) * COS(p1.lat) AS dx,             p1.R * (p2.lat - p1.lat) AS dy         FROM `gps_rad`             p1 JOIN `gps_rad` p2         ON (p1.`name` = 'location 1' AND p2.`name` = 'location 2')     ) t;

Calculating Distance from GPS data

End Result .... msyql> SELECT SQRT(dx * dx + dy * dy) AS distance            FROM (                SELECT                    p1.R * (p2.lon - p1.lon) * COS(p1.lat) AS dx,                    p1.R * (p2.lat - p1.lat) AS dy                FROM `gps_rad`                    p1 JOIN `gps_rad` p2                ON (p1.`name` = 'Cybertek' AND p2.`name` = 'Sydney')            ) t ;

+-----------------+| distance        |+-----------------+| 13378.204147479 |+-----------------+

Get all possible permutations

By using a cross-join (often done accidentally), SQL can generate all possible permutations of list items.

Example

You have two lists of names, and you want to setup a members schedule for Fight Club:

mysql> SELECT                 `names1`.`name` AS 'member', 'vs.',                `names2`.`name` AS 'opponent'            FROM `names1`, `names2`;

Generate a Random Permutation

Sometimes you want to generate a random pairing of field values.

Example

You suddenly need a random dance-off to get the party started:

Step 1 : Create a view of random entries

mysql> CREATE VIEW `rand_villians`                 AS            SELECT `name`             FROM `names2`             ORDER BY RAND()             LIMIT 5 ;

Generate a Random Permutation

Step 2 : Pair up the standard list with the random list.

mysql> SELECT `names1`.`name` AS 'member', 'vs.',                 `rand_villians`.`name` AS 'opponent'             FROM `names1`, `rand_villians`             GROUP BY `names1`.`name`             ORDER BY RAND()             LIMIT 1;

Sample Output

+--------+-----+-----------+| member | vs. | opponent  |+--------+-----+-----------+| Edd    | vs. | Brad Pitt |+--------+-----+-----------+

ASCII Art - Graphing with SQLWith a bit of (not-so-clever) trickery, we can generate vertical bar graphs of simple data sets using the REPEAT() function.

Example

mysql> SELECT `name`, REPEAT('#', `time`)             FROM `race_times` ; +-----------+----------------------+| name      | race_time            |+-----------+----------------------+| Ralfe     | ########             || Edd       | #################### || Rodney    | ###########          || Matt      | ######               || Karl      | #####                || Richard   | #####                |+-----------+----------------------+

Sorting Email

Sometimes, it is handy to group email addresses by their domain names. This would enable to, for example, allow you to see all email addresses from a particular company.

Example

msyql> SELECT          SUBSTRING(`e` FROM POSITION('@' IN `e`) + 1) as domain,          SUBSTRING(`e` FROM 1 FOR POSITION('@' IN `e`) -1) as account        FROM `email`        ORDER BY domain, account ;

SQL Calendar

In this more advanced hack, we will use a table of events to output a nicely formatted tabular calendar using only SQL.

Step 1

Create the table that holds the event data.

mysql> CREATE TABLE `bookings` (    `date` date,    `name` varchar(30)) ;

INSERT INTO `bookings` VALUES('2008-11-28', "Ralfe") ;INSERT INTO `bookings` VALUES('2008-11-29', "Karl") ;

SQL Calendar

Step 2

– Setup a view with the first day of the month (to use as a reference point).

CREATE VIEW dayOne AS SELECT DATE '2008-11-01' AS first;

– Create a table with all days of the month in it.

CREATE TABLE `cal` (`d` DATE);– Create a VIEW with the week beginings.

CREATE VIEW weekBeginning ASSELECT DAYOFMONTH(`d`) - DAYOFWEEK(`d`) AS wkFROM `cal` JOIN dayOneON (MONTH(`d`) = MONTH(first))GROUP BY wk;

SQL Calendar

Step 3

Create a Calendar Grid in the form of a VIEW

mysql> CREATE VIEW `calGrid` AS                SELECT wk, first + INTERVAL wk + 0 DAY AS Sun,                    first + INTERVAL wk + 1 DAY AS Mon,                    first + INTERVAL wk + 2 DAY AS Tue,                    first + INTERVAL wk + 3 DAY AS Wed,                    first + INTERVAL wk + 4 DAY AS Thu,                    first + INTERVAL wk + 5 DAY AS Fri,                    first + INTERVAL wk + 6 DAY AS Sat                FROM `weekBeginning` CROSS JOIN `dayOne` ;     

SQL CalendarStep 4                     (the last one, I promise)

Overlay the event data over your calendar grid.

mysql> SELECTCOALESCE((SELECT name FROM bookings WHERE date=Sun),DAYOFMONTH(Sun))    AS Sun,COALESCE((SELECT name FROM bookings WHERE date=Mon),DAYOFMONTH(Mon))    AS Mon,COALESCE((SELECT name FROM bookings WHERE date=Tue),DAYOFMONTH(Tue))    AS Tue,COALESCE((SELECT name FROM bookings WHERE date=Wed),DAYOFMONTH(Wed))    AS Wed,COALESCE((SELECT name FROM bookings WHERE date=Thu),DAYOFMONTH(Thu))    AS Thu,COALESCE((SELECT name FROM bookings WHERE date=Fri),DAYOFMONTH(Fri))    AS Fri,COALESCE((SELECT name FROM bookings WHERE date=Sat),DAYOFMONTH(Sat))    AS SatFROM `calGrid`ORDER BY `wk` ;    

SQL Calendar

The End Result ...

+------+------+------+------+------+-------+------+| Sun  | Mon  | Tue  | Wed  | Thu  | Fri   | Sat  |+------+------+------+------+------+-------+------+| 26   | 27   | 28   | 29   | 30   | 31    | 1    || 2    | 3    | 4    | 5    | 6    | 7     | 8    || 9    | 10   | 11   | 12   | 13   | 14    | 15   || 16   | 17   | 18   | 19   | 20   | 21    | 22   || 23   | 24   | 25   | 26   | 27   | Ralfe | Karl || 30   | 1    | 2    | 3    | 4    | 5     | 6    |+------+------+------+------+------+-------+------+

Magical

Google-like Search Rankings

Returning results from a string comparison can be quite meaningless most of the time.

Often, there is little or no meaning implied within the result set.

Introducing the wonders of SQL

MATCH() AGAINS()

Google-like Search Results

Step 1

Set up your data table.

myqsl> CREATE TABLE `books` (    `author` varchar(100),    `blerb` varchar(1000) ) ;

Google-like Search Results

Step 2

In order to do a FULLTEXT pattern match in MySQL, we will first need to create a FULLTEXT index on the field we want to match against.  Examplemysql> ALTER TABLE `books` ADD FULLTEXT(`blerb`) ;

Coogle-like Search Results

Step 3

Construct Your Search Query.

Example

Searching for "database systems"

mysql> SELECT `author`,     MATCH (`blerb`) AGAINST ('database systems')FROM `books`ORDER BY 2 DESC;

Google-like Search Results

The End Result ....

+---------------------+-----------------+| author              | relevance       |+---------------------+-----------------+| Atzeni              | 1.3253291845322 || Adams               |               0 || Russell and Cumming |               0 |+---------------------+-----------------+

References

Cumming, A. and Russel, G, 2007. "SQL Hacks: Tips & Tools for Digging into Your Data"Mike Chirico, "MySQL Tips", 2007,http://souptonuts.sourceforge.net/readme_mysql.htm

"Code Idol", 2008,http://codeidol.com/sql/sql-hack/Number-Crunching/Calculate-the-Distance-Between-GPS-Locations/

top related