结合多个MySQL查询返回不同的列

时间:2016-12-27 08:27:36

标签: mysql sql join union

我使用3个不同的mysql查询和JOINS从4个不同的表中获取数据。

MySQL Query 1

SELECT tb1.request_item_id AS most_requested_item_id, tb2.item_name AS most_requested_item_name
FROM  `requests` tb1 
LEFT JOIN `items` tb2 ON tb1.request_item_id = tb2.item_id
GROUP BY tb1.request_item_id
ORDER BY COUNT(*) DESC
LIMIT 3

查询1输出

  most_requested_item_id | most_requested_item_name
         87              | Poster FLS
         95              | Sample Item 4
         89              | Earth

查询2

  SELECT tb1.user_credit AS highest_credit_value, tb1.user_full_name AS highest_credit_user 
  FROM users tb1 
  ORDER BY tb1.user_credit 
  DESC LIMIT 3

查询2输出

   highest_credit_value | highest_credit_user
          140           | User A
          11            | User B
          10            | User C

查询3

SELECT tb1.credit_user_id AS credit_monthly_user, 
       SUM(tb1.credit_amount) AS totalCredit_monthly, 
       tb2.user_full_name AS monthly_credit_user 
FROM `credit_log` tb1 
LEFT JOIN users tb2 ON tb1.credit_user_id = tb2.user_id 
WHERE tb1.credit_date BETWEEN (CURDATE() - INTERVAL 30 DAY) AND CURDATE() 
GROUP BY credit_user_id 
ORDER BY totalCredit_monthly DESC 
LIMIT 3

查询3输出

     credit_monthly_user | totalCredit_monthly Descending 1 | monthly_credit_user
     User C              | 350                              | User D
     User E              | 170                              | User F
     User G              | 70                               | User H

我的SQL查询

(SELECT tb1.request_item_id AS most_requested_item_id, tb2.item_name AS most_requested_item_name
FROM  `requests` tb1 LEFT JOIN `items` tb2
ON tb1.request_item_id = tb2.item_id
GROUP BY tb1.request_item_id
ORDER BY COUNT(*) DESC
LIMIT 3)
UNION
(SELECT tb1.user_credit AS highest_credit_value, tb1.user_full_name AS highest_credit_user
FROM users tb1
ORDER BY tb1.user_credit DESC
LIMIT 3)
UNION
(SELECT tb1.credit_user_id AS credit_monthly_user, SUM(tb1.credit_amount) AS totalCredit_monthly, tb2.user_full_name AS monthly_credit_user
FROM `credit_log` tb1 LEFT JOIN users tb2 
ON tb1.credit_user_id = tb2.user_id
WHERE tb1.credit_date
BETWEEN (CURDATE() - INTERVAL 30 DAY) AND CURDATE()
GROUP BY credit_user_id 
ORDER BY totalCredit_monthly 
DESC LIMIT 3) 

所需输出

   most_requested_item_id | most_requested_item_name | highest_credit_value | highest_credit_user | credit_monthly_user | totalCredit_monthly Descending 1 | monthly_credit_user
          87              | Poster FLS               | 140                  | User A              |  User C             | 350                              | User D
          95              | Sample Item 4            | 11                   | User B              | User E              | 170                              | User F
          89              | Earth                    | 10                   | User C              | User G              | 70                               | User H  

但是我收到了一个错误:

  

使用的select语句具有不同数量的列union

credit_log

的架构
  Field         | Type         | Null | Key | Default| Extra
  credit_log_id | int(11)      | NO   | PRI | NULL   | auto_increment
  credit_user_id| varchar(255) | YES  |     | NULL   |
  credit_date   | datetime     | YES  |     | NULL   |
  credit_amount | int(11)      | YES  |     | NULL   |
  credit_type   | varchar(255) | YES  |     | NULL   |
  credit_desc   | varchar(255) | YES  |     | NULL   |

请求

的架构
  Field                | Type         | Null | Key | Default           | Extra
  request_id           | int(11)      | NO   | PRI | NULL              |  auto_increment
  request_requser_id   | varchar(255) | NO   | PRI
  request_item_id      | varchar(255) | NO   | PRI
  request_status       | varchar(20)  | NO   |     | Active
  request_lastmodified | datetime     | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP
  request_message      | varchar(225) | YES  |     | NULL

的架构
  Field                   | Type         | Null | Key     | Default           | Extra
  item_id                 | int(11)      | NO   | PRI     | NULL              | auto_increment
  item_name               | varchar(255) | NO   |         | NULL
  item_category           | varchar(255) | NO   |         | NULL
  item_desc               | varchar(255) | YES  |         | NULL
  item_user_id            | varchar(255) | YES  |         | NULL
  item_lease_value        | int(11)      | YES  |         | NULL
  item_lease_term         | varchar(255) | YES  |         | NULL
  item_image              | mediumtext   | YES  |         | NULL
  item_primary_image_link | varchar(255) | YES  |         | NULL
  item_status             | varchar(255) | NO   | Created |
  item_uid                | varchar(255) | YES  |         | NULL
  item_lat                | float(10,6)  | YES  |         | NULL
  item_lng                | float(10,6)  | YES  |         | NULL
  item_lastmodified       | datetime     | NO             | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP

用户的架构。

users_table

有没有办法将上述3个查询合并为一个,以便返回总共7列?请帮忙

1 个答案:

答案 0 :(得分:1)

考虑按行号或排名加入所有查询。由于它们都是不相关的部分,我们可以根据它们共享的行位置进行匹配。下面将查询作为在外部主查询中连接在一起的派生表运行。

具体来说,前两个派生表使用相关计数子查询,而最后一个使用已定义的变量(因为最后一个更复杂,因为排序是在聚合值上运行,与其他值不同)。如果count聚合不起作用,请为所有使用变量。并且LEFT JOIN超过INNER JOIN用于案例排名不匹配,并且带有NULL的行将出现在您可以相应调整排名计算的位置。现在,每个查询' 排名输出。关系可能也是一个问题。

SELECT main1.*, main2.*, main3.*
FROM
  (SELECT r.request_item_id AS most_requested_item_id, i.item_name AS most_requested_item_name,
          (SELECT Count(*) FROM `requests` sub 
           WHERE sub.request_item_id >= r.request_item_id) AS rank
   FROM `requests` r 
   LEFT JOIN `items` i ON r.request_item_id = i.item_id
   GROUP BY r.request_item_id, i.item_name
   ORDER BY COUNT(*) DESC
   LIMIT 3) main1

LEFT JOIN
  (SELECT u.user_credit AS highest_credit_value, u.user_full_name AS highest_credit_user,        
          (SELECT Count(*) FROM `users` sub 
           WHERE sub.user_credit >= u.user_credit) AS rank
   FROM `users` u
   ORDER BY u.user_credit DESC
   LIMIT 3) main2
ON main1.rank = main2.rank

LEFT JOIN
  (SELECT c.credit_user_id AS credit_monthly_user, SUM(c.credit_amount) AS totalCredit_monthly,
           u.user_full_name AS monthly_credit_user,
           (@rownum:= @rownum + 1) AS rank
   FROM `credit_log` c, (select @rownum := 0) sqlvars,
   LEFT JOIN `users` u ON c.credit_user_id = u.user_id
   WHERE c.credit_date BETWEEN (CURDATE() - INTERVAL 30 DAY) AND CURDATE()
   GROUP BY c.credit_user_id, u.user_full_name
   ORDER BY totalCredit_monthly DESC 
   LIMIT 3) main3
ON main1.rank = main3.rank