2016-12-27 10 views
-2

Я получаю данные из 4 разных таблиц, используя 3 разных запроса mysql и JOINS.Объединить несколько запросов MySQL, возвращающих разные столбцы

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 

Query 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 

Но я получаю сообщение об ошибке:

The used select statements have a different number of columns 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 столбцов ?? Пожалуйста, помогите

+0

См http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very -simple-sql-query – Strawberry

+1

можете ли вы отправить схему таблицы и получить результат? –

+0

, но не обязательно, размещение ссылки на SQL Fiddle (http://sqlfiddle.com) может быть очень выгодным для таких проблем. – Jhecht

ответ

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