如何使用最佳方法在一行中获取多个字段的不同计数


How to get distinct count of many fields in one row using best possible method

我的演示数据库中有 2 个表,我根据 2 个键将它们连接起来,在这里我想计算匹配结果的不同,

我的第一张桌子

MariaDB [demos]> select * from main_info;
+------+------+-------+-------+----------+
| key1 | key2 | info1 | info2 | date     |
+------+------+-------+-------+----------+
|    1 |    1 |    15 |    90 | 20120501 |
|    1 |    2 |    14 |    92 | 20120601 |
|    1 |    3 |    15 |    82 | 20120801 |
|    2 |    1 |    17 |    90 | 20130302 |
|    2 |    2 |    16 |    88 | 20130601 |
+------+------+-------+-------+----------+
5 rows in set (0.00 sec)

还有我的第二张桌子

MariaDB [demos]> select * from product1;
+------+------+--------+--------------+
| key1 | key2 | serial | product_data |
+------+------+--------+--------------+
|    1 |    1 |      0 | NaN          |
|    1 |    1 |      1 | NaN          |
|    1 |    1 |      2 | NaN          |
|    1 |    1 |      3 | NaN          |
|    1 |    2 |      0 | 12.556       |
|    1 |    2 |      1 | 13.335       |
|    1 |    3 |      1 | NaN          |
|    1 |    3 |      2 | 13.556       |
|    1 |    3 |      3 | 14.556       |
|    2 |    1 |      0 | 12.556       |
|    2 |    1 |      1 | 13.553       |
|    2 |    1 |      2 | NaN          |
+------+------+--------+--------------+
12 rows in set (0.00 sec)

因此,字段串行的不同计数如下,其中串行不为零

MariaDB [demos]> select count(distinct a.key1,a.key2) as serial_count from main_info a,product1 b where a.key1=b.key1 and a.key2=b.key2 and b.serial !=0;
+--------------+
| serial_count |
+--------------+
|            4 |
+--------------+
1 row in set (0.00 sec)

字段product_data的不同计数如下,其中product_data不是 NaN

MariaDB [demos]> select count(distinct a.key1,a.key2) as product_count from main_info a,product1 b where a.key1=b.key1 and a.key2=b.key2 and b.product_data !='NaN';
+---------------+
| product_count |
+---------------+
|             3 |
+---------------+
1 row in set (0.00 sec)

在我的原始应用程序中,我的表中有很多列,最后我想使用单个查询获得如下所示的结果,目前我正在使用 PHP 进行多个查询,这需要很长时间,因为例如如果我有 100 列,我必须像上面一样执行 100 次函数,所以请有人指导我加快我的应用程序

+--------------+---------------+
| serial_count |product_count  |
+--------------+---------------+
|    4         |    3          |
+--------------+---------------+

以下是表格的结构

DROP TABLE IF EXISTS `main_info`;
CREATE TABLE `main_info` (
  `key1` int(11) NOT NULL,
  `key2` int(11) NOT NULL,
  `info1` int(11) NOT NULL,
  `info2` int(11) NOT NULL,
  `date` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

LOCK TABLES `main_info` WRITE;
INSERT INTO `main_info` VALUES (1,1,15,90,20120501),(1,2,14,92,20120601),(1,3,15,82,20120801),(2,1,17,90,20130302),(2,2,16,88,20130601);
UNLOCK TABLES;

DROP TABLE IF EXISTS `product1`;
CREATE TABLE `product1` (
  `key1` int(11) NOT NULL,
  `key2` int(11) NOT NULL,
  `serial` int(11) NOT NULL,
  `product_data` varchar(1000) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

LOCK TABLES `product1` WRITE;
INSERT INTO `product1` VALUES (1,1,0,'NaN'),(1,1,1,'NaN'),(1,1,2,'NaN'),(1,1,3,'NaN'),(1,2,0,'12.556'),(1,2,1,'13.335'),(1,3,1,'NaN'),(1,3,2,'13.556'),(1,3,3,'14.556'),(2,1,0,'12.556'),(2,1,1,'13.553'),(2,1,2,'NaN');
UNLOCK TABLES;

我不明白为什么日期类型会改变,如果我在终端上运行

$ mysql -u root -p demos -e 'select key1,if(key1 !=0,key1,999.999) as `test1` from main_info'
Enter password: 
+------+-------+
| key1 | test1 |
+------+-------+
|    1 | 1.000 |
|    1 | 1.000 |
|    1 | 1.000 |
|    2 | 2.000 |
|    2 | 2.000 |
+------+-------+

我希望如果条件为真IF它应该是整数

您可以使用条件聚合在单个查询中执行此操作:

select count(distinct if(b.product_data !='NaN',a.key1, null),  
                      if(b.product_data !='NaN',a.key2, null)) as product_count,
       count(distinct if(b.serial !=0,a.key1, null),  
                      if(b.serial !=0,a.key2, null)) as serial_count                     
from main_info a
inner join product1 b on a.key1=b.key1 and a.key2=b.key2

输出:

product_count   serial_count
-----------------------------
3               4

在这里演示

编辑:功劳归于@Paul斯皮格尔

可以使用CONCAT简化查询:

select count(distinct if(b.product_data !='NaN', 
                         CONCAT(a.key1, ',', a.key2), 
                         null)) as product_count,
       count(distinct if(b.serial !=0, 
                         CONCAT(a.key1, ',', a.key2), 
                         null)) as serial_count                     
from main_info a
inner join product1 b on a.key1=b.key1 and a.key2=b.key2