The Oracle feature set is often brought up as an argument (for? against?) when comparing it against other databases. And it is indeed a huge feature set and it's pretty great to use, but granted, the Oracle documentation can be pretty dry to read.
For example, check out the documentation for the NTILE Function. Yeah, sounds kind of boring. What good could it be in the wonderful world of web development? After all, who manages employee or sales tables anymore...
Answer: generating tag clouds.
It's kind of a pain to make pretty tag clouds and if you google for how to do it in an elegant way, you'll most likely find a lot of cumbersome looping through arrays over and over and assigning some variables and doing some weird math on them. Not very elegant at all.
Here's how you do it (elegantly) using the NTILE function instead:
SELECT name tag_name,
num_results_per_tag,
ntile($numFontSizesInCloud) over (ORDER BY num_results_per_tag) as font_size
FROM (SELECT name,
num_results_per_tag
FROM tag
ORDER BY num_results_per_tag DESC)
WHERE rownum <= :num_tags
ORDER BY name;
What this query does is take all tags and number of items tagged with that tag and orders them by that number (so most popular tags first). You can specify how many tags to retrieve for the clouds via the :num_tags parameter. (Note: instead of using this clause to limit number of tags by their row number, you can use a subquery to retrieve a specific set of tags, e.g. user-specific tags, page-specific tags, etc.)
After you know how many tags to retrieve, you use the NTILE function to put all the tags into "buckets", or font sizes (or classes) your tag cloud will use. How many buckets you have depends purely on your whim and you can specify it when constructing the query using $numFontSizesInCloud (or some other cleverly named variable). (Note that this value is not bound as it is not a parameter for the SELECT statement.)
The NTILE function creates however many buckets you want, then it evaluates the data in the OVER clause to assign the bucket to each of the tags returned. In your template then, you can simply display a tag cloud like this:
It's then up to your CSS to define font sizes or whatever class names you want to give them (don't quote me on my CSS usage...) and you're done!
Comments (1)
If you want to try the query out in SQL*Plus, use this script:
drop table tag;
create table tag (name varchar2(20), num_results_per_tag number);
insert into tag (name, num_results_per_tag) values ('apple', 20);
insert into tag (name, num_results_per_tag) values ('oracle', 1);
insert into tag (name, num_results_per_tag) values ('banana', 5);
insert into tag (name, num_results_per_tag) values ('kiwi', 43);
insert into tag (name, num_results_per_tag) values ('pawpaw', 7);
insert into tag (name, num_results_per_tag) values ('pear', 30);
insert into tag (name, num_results_per_tag) values ('starfruit', 8);
insert into tag (name, num_results_per_tag) values ('mangosteen', 3);
insert into tag (name, num_results_per_tag) values ('rambutan', 10);
insert into tag (name, num_results_per_tag) values ('coconut', 13);
insert into tag (name, num_results_per_tag) values ('durian', 13);
-- Number of different size fonts that can be displayed
define numFontSizesInCloud = 5
-- Number of tags to be displayed
var num_tags number
exec :num_tags := 7
Now run Maggie's query, after changing the PHP variable
$numFontSizesInCloud to a SQL*Plus variable &numFontSizesInCloud
My output is:
TAG_NAME NUM_RESULTS_PER_TAG FONT_SIZE
-------------------- ------------------- ----------
apple 20 3
coconut 13 2
durian 13 2
kiwi 43 5
pear 30 4
rambutan 10 1
starfruit
Posted by CJ | May 1, 2008 1:43 PM
Posted on May 1, 2008 13:43