CrossTab query (Pivot Table or Transformation of rows into columns)

CrossTab query is amazing, which helps generating reports and play with aggregate values. Excel/Ms Access gives nice user interface for Pivot Table. It’s way to transfer rows into column. It is more often used to generate matrix form of report. Some real-life example:

1. Give me last 3 months sales report product wise. (It may look like below)

Month -->  | Jan    |  Feb     | March
---------- | ------ | -------- | -------
Product A  | 3387   | 87985    | 2338
Product B  | 6386   | 67983    | 6374
Product C  | 3880   | 76988    | 9378
..... and product lists goes down ....

2. Give me last 3 months sales report country wise. (It may look like below)

Country -> | USA    |  France  | Japan
---------- | ------ | -------- | -------
Jan        | 3387   | 87985    | 2338
Feb        | 6386   | 67983    | 6374
Mar        | 3880   | 76988    | 9378

#1 and #2 can be ask like ‘Give me top-ten selling products in last 3 months, or give me top-ten selling countries in last 3 months”

If you see field name (column title)  in #1, it’s name of month (date), which is row data and similarly country is row data in #2. They are not field name in database table. It is possible to get reports like above by transforming rows into columns. This is what called Pivot Table, and can be done using CrossTab query. Let’s take bit example (example belows are used with MySQL):

1. Create Database, tables and insert dummy data. Use script below:

CREATE TABLE  `products` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`product` VARCHAR( 100 ) NOT NULL
);

CREATE TABLE  `sales` (
	`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
	`product_id` INT NOT NULL ,
	`qty` INT NOT NULL,
	`sales_date` DATETIME NOT NULL
)

INSERT INTO `products` (`id`, `product`) VALUES
(1, 'Fanta'),
(2, 'Coke'),
(3, 'Mirinda'),
(4, 'Sprite');

INSERT INTO `sales`
(`id`, `sold_date`, `product_id`, `qty`)
VALUES
(1, '2011-02-07 11:49:53', 1, 4),
(2, '2011-02-07 11:49:53', 1, 4),
(3, '2011-02-08 11:50:05', 1, 8),
(4, '2011-02-07 11:49:53', 2, 5),
(5, '2011-02-07 11:49:53', 3, 2),
(6, '2011-02-08 11:50:05', 2, 7),
(7, '2011-02-07 11:49:53', 3, 5),
(8, '2011-02-07 11:49:53', 4, 2),
(9, '2011-02-08 11:50:05', 3, 7),
(10, '2011-02-07 11:49:53', 2, 5),
(11, '2011-02-07 11:49:53', 3, 2),
(12, '2011-02-08 11:50:05', 4, 7);

2. Determine output you want (in our case, below is format):

Date       | Fanta  | Coke   | Mirinda | Sprite
xxxx:xx:xx | x      | x      | x       | x
xxxx:xx:xx | x      | x      | x       | x

3. Write query, run it:

SELECT
	s.sales_date `Sales Date`,
	SUM(IF(p.product='Fanta', s.qty, 0)) Fanta,
	SUM(IF(p.product='Coke', s.qty, 0))  Coke,
	SUM(IF(p.product='Mirinda', s.qty, 0)) Mirinda,
	SUM(IF(p.product='Sprite', s.qty, 0))  Sprite
FROM
	products p,
	sales s
WHERE
	p.id = s.product_id
GROUP BY
	s.sales_date

4. Output is as given below:

Date                 | Fanta  | Coke   | Mirinda | Sprite
2011-02-07 11:49:53  | 8      | 10     | 9       | 2
2011-02-08 11:50:05  | 8      | 7      | 7       | 7

Perl beginner – install and run hello world, MySQL test

I am seasoned PHP programmer, been around ten years I am coding on PHP. Although I learn and tried many different programming languages, I always scare to give a try to Perl. I was in impression that Perl is difficult language so never get confident to try it, or never can arrange time for it. But, today as I was working on Asterisk for VoIP system, there’s was no choice left, but Perl.

I gave first try today in Ubuntu. It wasn’t that bad as I heard. Actually I was wrong about Perl, it was proved.

Below is how, I tried first hello world and first database application

Install Perl

  1. $ sudo apt-get install perl

 

Don’t worry, if Perl is already installed, it do nothing. If you have Ubuntu server edition, Perl is already there.

 

Create directory called perl_test. Create perl_test.pl file and save following content.

  1. #!/usr/bin/perl
  2. #simple perl program to print the user input
  3. print ("Hello world! test goes this\n");
  4. $inputline=<stdin>;
  5. print ($inputline);

 

Save file named as perl_test.pl and run following command.

  1. $ sudo chmod +x perl_test.pl
  2. $ ./perl_test.pl

 

Database Test:
Create perl_db.pl file and save following content.

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use DBI;
  5.  
  6. my $username='test';
  7. my $pass='test';
  8. my $db='test';
  9. my $dbh = DBI->connect( "dbi:mysql:$db", $username, $pass, { 'PrintError' => 1, 'RaiseError' => 1 } );
  10. my $sql='select * from test';
  11. my $sql_handle=$dbh->prepare($sql);
  12. $sql_handle->execute();
  13. my @data;
  14. while (@data=$sql_handle->fetchrow_array()) {
  15. print join("\n",@data)
  16. }

 

  1. $ sudo chmod +x perl_db.pl
  2. $ sudo ./perl_db.pl

 

Make sure user test with password test and database test exits. And it has test table.

 
Haurry!!!