【问题标题】:Combine multiple MySQL queries returning different columns组合多个返回不同列的 MySQL 查询
【发布时间】:2016-12-27 08:27:36
【问题描述】:

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

MySQL 查询 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 表的架构。

有没有什么方法可以将上述 3 个查询合并为一个,从而返回总共 7 列?请帮忙

【问题讨论】:

  • 你能发布表格架构和想要的结果吗?
  • 虽然不是必需的,但发布指向 SQL Fiddle (sqlfiddle.com) 的链接对于此类问题非常有利。
  • 只是问,表有外键吗?
  • 您不需要联合查询(垂直堆叠),而是所有选择的连接(水平合并)。但是,我看到的唯一连接组织是user 级别。 requestsitems 如何与 users 表关联?

标签: mysql sql join union


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多