Solved

Creating crosstab query using COUNT gives incorrect row and column totals

Posted on 2004-09-15
1
436 Views
Last Modified: 2012-08-14
Can someone tell me why the row and column totals compute properly with this crosstab query (using SUM):
MySQL Version: 4.0.20-standard

#crosstab
SELECT MONTHNAME(dt),
      SUM(IF(category = 'A',id, 0)) AS 'cat a',
      SUM(IF(category = 'B',id, 0)) AS 'cat b',
      SUM(IF(category = 'C',id, 0)) AS 'cat c',
#row totals
      SUM(id) AS 'TOTAL'
FROM t1
GROUP BY MONTH(dt)
UNION
#column totals
SELECT 'YTD',
      SUM(IF(category = 'A',id, 0)) AS 'cat a',
      SUM(IF(category = 'B',id, 0)) AS 'cat b',
      SUM(IF(category = 'C',id, 0)) AS 'cat c',
      SUM(id) AS 'TOTAL'
FROM t1;

But, this same crosstab query using COUNT, gives incorrect Totals:

#crosstab
SELECT MONTHNAME(dt),
      COUNT(DISTINCT(IF(category = 'A',id, 0))) AS 'cat a',
      COUNT(DISTINCT(IF(category = 'B',id, 0))) AS 'cat b',
      COUNT(DISTINCT(IF(category = 'C',id, 0))) AS 'cat c',
#row totals
      COUNT(DISTINCT(id)) AS 'TOTAL'
FROM t1
GROUP BY MONTH(dt)
UNION
#column totals
SELECT 'YTD',
      COUNT(DISTINCT(IF(category = 'A',id, 0))) AS 'cat a',
      COUNT(DISTINCT(IF(category = 'B',id, 0))) AS 'cat b',
      COUNT(DISTINCT(IF(category = 'C',id, 0))) AS 'cat c',
      COUNT(DISTINCT(id)) AS 'TOTAL'
FROM t1;

-------------------------------------------------
Here's the table structure:
CREATE TABLE `t1` (                                                                                                                                      
         `id` int(11) NOT NULL default '0',                                                                                                                      
         `category` char(2) default NULL,                                                                                                                        
         `dt` date default NULL,                                                                                                                                
         PRIMARY KEY  (`id`)                                                                                                                                    
---------------------------------------------------
Here's the data:
1,A,2004-01-01,
2,B,2004-04-01,
3,C,2004-02-01,
4,A,2004-05-01,
5,B,2004-03-01,
6,C,2004-04-01,
7,A,2004-06-01,
8,B,2004-01-01,

--------------------------------------------------
I haven't been able to find anything on this topic via internet searches.
0
Comment
Question by:dplinnane
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 12

Accepted Solution

by:
AdrianSRU earned 500 total points
ID: 12070426
COUNT gives the number of non-null values.

COUNT(DISTINCT(IF(category = 'A',id, 0)))
will not be null unless id is null.

Try this:
COUNT(DISTINCT(IF(category = 'A',id, NULL)))


-Adrian
0

Featured Post

Get Database Help Now w/ Support & Database Audit

Keeping your database environment tuned, optimized and high-performance is key to achieving business goals. If your database goes down, so does your business. Percona experts have a long history of helping enterprises ensure their databases are running smoothly.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I use MySQL for many of my development projects in a Windows environment. To manage my databases (and perform queries) for years I used a tool called MySQL administrator.  This tool has since been replaced by MySQL Workbench. So I decided to m…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question