2017-06-28 75 views
1

我有连接表的问题,这些表与其他表没有关系。MYSQL连接表和范围

表结构

用户

╔════╦═════════════╗ 
║ ID ║ Name  ║ 
╠════╬═════════════╣ 
║ 1 ║ Jon   ║ 
║ 2 ║ Mark  ║ 
║ 3 ║ Tom   ║ 
╚════╩═════════════╝ 

机会

╔════╦════════════╦═════════════╗ 
║ ID ║ user_id ║ total_price ║ 
╠════╬════════════╬═════════════╣ 
║ 1 ║ 2   ║ 1500  ║ 
║ 2 ║ 2   ║ 2000  ║ 
║ 3 ║ 1   ║ 1000  ║ 
╚════╩════════════╩═════════════╝ 

水平

╔════╦════════════╦═════════════╦══════════╦════════╗ 
║ ID ║ Name  ║ parent_id ║ min  ║target ║ 
╠════╬════════════╬═════════════╬══════════╬════════╣ 
║ 1 ║ Golden  ║  0  ║ 1000  ║ 5000 ║ 
║ 2 ║ golden-1 ║  1  ║ 1000  ║ 2500 ║ 
║ 3 ║ golden-2 ║  1  ║ 2551  ║ 5000 ║ 
║ 4 ║ Silver  ║  0  ║ 500  ║ 999 ║ 
║ 5 ║ Silver-1 ║  4  ║ 500  ║ 750 ║ 
╚════╩════════════╩═════════════╩══════════╩════════╝ 

我想获得用户的水平,如果他的机会总和总价范围内min水平和target 之间我这个查询尝试,但它显示错误[HY000][1111] Invalid use of group function

SELECT 
    `users`.`id`     AS `user_id`, 
    `users`.`name`     AS `user_name`, 
    SUM(opportunities.total_price) AS `total_target`, 
`levels`.`name`     As `Level_name` 
FROM `users` 
    INNER JOIN `opportunities` ON `users`.`id` = `opportunities`.`user_id` 
    INNER JOIN `levels` ON SUM(opportunities.total_price) >= levels.min 
         AND SUM(opportunities.total_price) <= levels.target 
WHERE `users`.`deleted_at` IS NULL 
GROUP BY user_id 

注:我使用Laravel 5.2

+0

'SUM'不能在'join'中使用。 “水平”与其他两张桌子有什么关系? – Blank

+0

你不能在任何我曾经使用过的数据库中加入SUM的结果。 –

+0

关卡表与任何其他表之间没有关系。 – Ahmed

回答

2

正如其他人已经在评论中指出的那样:您不能直接在连接中使用聚合函数。连接操作发生在聚合之前。

您需要在连接之前进行聚合- 因此您需要计算子查询中的总和。通过这种方式,您可以将总和引用为联接中的普通字段。

select t.*, levels.name as level_name 
from levels l 
inner join 
(SELECT 
    `users`.`id`     AS `user_id`, 
    `users`.`name`     AS `user_name`, 
    SUM(opportunities.total_price) AS `total_target` 
FROM users 
INNER JOIN `opportunities` ON `users`.`id` = `opportunities`.`user_id` 
WHERE `users`.`deleted_at` IS NULL 
GROUP BY users.id, users.name) t on t.total_target>=l.min and t.total_target<=l.target 

但是,我注意到你有层次结构。上面的查询将为每个用户在单独的记录中返回主级别和子级别。

1

如果您确实需要在一次通话中完成此操作,以下方法可能会使您开始朝正确的方向发展。

基本上,解决方案是从派生表中进行选择并加入。

我还没有去测试它,所以可能会有语法错误。

select 
c.`user_id` `user_id`, 
c.`user_name` `user_name`, 
c.total_target `total_target`, 
d.`Name`  `Level_name` 
from 
(select 
`id`    `user_id`, 
`name`   `user_name`, 
sum(total_price) `total_target` 
from `users` a 
join `opportunites` b 
on a.ID = b.user_id 
group by user_id) c 
join levels d 
on c.total_target >= d.min 
and c.total_target =< d.target