use*_*224 5 mysql sql join mariadb
这个问题是关于查询优化,以避免通过PHP多次调用数据库.
所以这是场景,我有两个表,其中包含您可以将其称为参考表的信息,另一个是数据表,字段key1
并且key2
在两个表中都是通用的,基于这些字段,我们可以加入它们.
我不知道查询是否可以比我现在正在做的更简单,我想要实现的如下:
我希望找到
key1,key2,info1,info2
与main_info
表不同的,每当串行值小于10并且key1,key2
两个表匹配时,然后将它们info1,info2
分组,而分组计数key1,key2
重复的info1,info2
字段和group_concat
那些键的重复
表的内容 main_info
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 |
| 1 | 4 | 15 | 82 | 20120801 |
| 1 | 5 | 15 | 82 | 20120802 |
| 2 | 1 | 17 | 90 | 20130302 |
| 2 | 2 | 17 | 90 | 20130302 |
| 2 | 3 | 17 | 90 | 20130302 |
| 2 | 4 | 16 | 88 | 20130601 |
+------+------+-------+-------+----------+
9 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
表的内容 product1
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 |
| 1 | 4 | 3 | NaN |
| 1 | 5 | 3 | NaN |
| 2 | 1 | 0 | 12.556 |
| 2 | 1 | 1 | 13.553 |
| 2 | 1 | 2 | NaN |
| 2 | 2 | 12 | 129 |
| 2 | 3 | 22 | NaN |
+------+------+--------+--------------+
16 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
通过PHP我在表的当前上下文中对表字段info1
和info2
表进行分组,多次一个接一个(这里我运行查询两次,你可以看到)main_info
serial
product_data
product1
对于字段serial
- 第一个查询
MariaDB [demos]> select * , count(*) as serial_count,GROUP_CONCAT(key1,' ',key2) as serial_ids from
-> (
-> SELECT distinct
-> if(b.serial < 10,a.key1,null) AS `key1`,
-> if(b.serial < 10,a.key2,null) AS `key2`,
-> if(b.serial < 10,a.info1,null) AS `info1`,
-> if(b.serial < 10,a.info2,null) AS `info2`
-> FROM main_info a inner join product1 b on a.key1 = b.key1 AND a.key2= b.key2
-> ) as sub group by info1,info2
-> ;
+------+------+-------+-------+--------------+-------------+
| key1 | key2 | info1 | info2 | serial_count | serial_ids |
+------+------+-------+-------+--------------+-------------+
| NULL | NULL | NULL | NULL | 1 | NULL |
| 1 | 2 | 14 | 92 | 1 | 1 2 |
| 1 | 3 | 15 | 82 | 3 | 1 3,1 4,1 5 |
| 1 | 1 | 15 | 90 | 1 | 1 1 |
| 2 | 1 | 17 | 90 | 1 | 2 1 |
+------+------+-------+-------+--------------+-------------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
对于字段product_data
- 第二个查询
MariaDB [demos]> select * , count(*) as product_data_count,GROUP_CONCAT(key1,' ',key2) as product_data_ids from
-> (
-> SELECT distinct
-> if(b.product_data IS NOT NULL,a.key1,null) AS `key1`,
-> if(b.product_data IS NOT NULL,a.key2,null) AS `key2`,
-> if(b.product_data IS NOT NULL,a.info1,null) AS `info1`,
-> if(b.product_data IS NOT NULL,a.info2,null) AS `info2`
-> FROM main_info a inner join product1 b on a.key1 = b.key1 AND a.key2= b.key2
-> ) as sub group by info1,info2
-> ;
+------+------+-------+-------+--------------------+------------------+
| key1 | key2 | info1 | info2 | product_data_count | product_data_ids |
+------+------+-------+-------+--------------------+------------------+
| 1 | 2 | 14 | 92 | 1 | 1 2 |
| 1 | 3 | 15 | 82 | 3 | 1 3,1 4,1 5 |
| 1 | 1 | 15 | 90 | 1 | 1 1 |
| 2 | 2 | 17 | 90 | 3 | 2 2,2 3,2 1 |
+------+------+-------+-------+--------------------+------------------+
4 rows in set (0.01 sec)
Run Code Online (Sandbox Code Playgroud)
我希望使用一个查询得到这样的输出,分组为info1,info2
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| key1 | key2 | info1 | info2 | serial_count | serial_ids | product_data_count | product_data_ids |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| NULL | NULL | NULL | NULL | 1 | NULL | NULL | NULL |
| 1 | 2 | 14 | 92 | 1 | 1 2 | 1 | 1 2 |
| 1 | 3 | 15 | 82 | 3 | 1 3,1 4,1 5 | 3 | 1 3,1 4,1 5 |
| 1 | 1 | 15 | 90 | 1 | 1 1 | 1 | 1 1 |
| 2 | 1 | 17 | 90 | 1 | 2 1 | 3 | 2 2,2 3,2 1 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
Run Code Online (Sandbox Code Playgroud)
下面是表格的结构
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),(1,4,15,82,20120801),(1,5,15,82,20120802),(2,1,17,90,20130302),(2,2,17,90,20130302),(2,3,17,90,20130302),(2,4,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'),(1,4,3,'NaN'),(1,5,3,'NaN'),(2,1,0,'12.556'),(2,1,1,'13.553'),(2,1,2,'NaN'),(2,2,12,'129'),(2,3,22,'NaN');
UNLOCK TABLES;
Run Code Online (Sandbox Code Playgroud)
有人请帮助我在一个查询中得到结果.
试试这个
SELECT
key1, key2, info1, info2,
SUM(Scount) AS serial_count, GROUP_CONCAT(Skey1, ' ', Skey2) AS serial_ids,
SUM(Pcount) AS product_data_count, GROUP_CONCAT(Pkey1, ' ', Pkey2) AS product_data_ids
FROM
(
SELECT DISTINCT
IF(b.serial < 10 OR b.product_data IS NOT NULL,a.key1, NULL) AS `key1`,
IF(b.serial < 10 OR b.product_data IS NOT NULL,a.key2, NULL) AS `key2`,
IF(b.serial < 10 OR b.product_data IS NOT NULL,a.info1, NULL) AS `info1`,
IF(b.serial < 10 OR b.product_data IS NOT NULL,a.info2, NULL) AS `info2`,
IF(b.serial < 10,a.key1, NULL) AS `Skey1`,
IF(b.serial < 10,a.key2, NULL) AS `Skey2`,
IF(b.product_data IS NOT NULL,a.key1, NULL) AS `Pkey1`,
IF(b.product_data IS NOT NULL,a.key2, NULL) AS `Pkey2`,
IF(b.serial < 10, 1, NULL) AS `Scount`,
IF(b.product_data IS NOT NULL, 1, NULL) AS `Pcount`
FROM main_info a INNER JOIN product1 b ON a.key1 = b.key1 AND a.key2= b.key2
UNION ALL
SELECT DISTINCT
NULL AS `key1`,
NULL AS `key2`,
NULL AS `info1`,
NULL AS `info2`,
NULL AS `Skey1`,
NULL AS `Skey2`,
NULL AS `Pkey1`,
NULL AS `Pkey2`,
IF(serial > 9, 1, NULL) AS `Scount`,
IF(product_data IS NULL, 1, NULL) AS `Pcount`
FROM product1 WHERE serial > 9 xor product_data IS NULL
) AS sub GROUP BY info1,info2
Run Code Online (Sandbox Code Playgroud)
结果(问题数据)
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| key1 | key2 | info1 | info2 | serial_count | serial_ids | product_data_count | product_data_ids |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| NULL | NULL | NULL | NULL | 1 | NULL | NULL | NULL |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 2 | 14 | 92 | 1 | 1 2 | 1 | 1 2 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 3 | 15 | 82 | 3 | 1 3,1 4,1 5 | 3 | 1 3,1 4,1 5 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 1 | 15 | 90 | 1 | 1 1 | 1 | 1 1 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
Run Code Online (Sandbox Code Playgroud)
结果(数据来自评论)
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| key1 | key2 | info1 | info2 | serial_count | serial_ids | product_data_count | product_data_ids |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| NULL | NULL | NULL | NULL | 1 | NULL | 1 | NULL |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 2 | 14 | 92 | 1 | 1 2 | 1 | 1 2 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 3 | 15 | 82 | 3 | 1 3,1 4,1 5 | 3 | 1 3,1 4,1 5 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 1 | 1 | 15 | 90 | 1 | 1 1 | 1 | 1 1 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 2 | 4 | 16 | 88 | 1 | 2 4 | 1 | 2 4 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
| 2 | 1 | 17 | 90 | NULL | NULL | 3 | 2 1,2 2,2 3 |
+------+------+-------+-------+--------------+-------------+--------------------+------------------+
Run Code Online (Sandbox Code Playgroud)
笔记:
我确实能理解问题背后的基本逻辑,所以主要根据预期结果来回答。例如,如果组字段 (info1
和info2
) 为 null,则其他结果将始终为 null,除了serial_count
和product_data_count
可以为 1 或 null,您真的想得到这个吗?请注意,这个答案使用另一个子查询来UNION ALL
满足这一点。
归档时间: |
|
查看次数: |
810 次 |
最近记录: |