关于与UNION结合的几个表之间的计算

时间:2018-09-06 09:39:29

标签: mysql sql database join select

我查询困难,现在我需要针对另一个表中的数据指定此查询的结果。二手的UNION。这样对吗?为什么我不工作?

SELECT * from (select IFnull(t.diapason,'total') as diapason, count(distinct 
user_id) / total_visitors*100 AS 'percent_of_users'
FROM 
(SELECT p.user_id, p.amount as total, CASE  
when amount<10 then '0-10' 
when amount>=10 then '10 +' END AS diapason
FROM 
    (SELECT payments.user_id, SUM(amount) AS amount 
    FROM payments INNER JOIN 
   (SELECT DISTINCT user_id, login_time FROM activity where login_time 
between '2018-04-12' and '2018-04-18') a 
ON payments.user_id = a.user_id and a.login_time = payments.payment_time 
GROUP BY payments.user_id) p
) t
  GROUP BY diapason WITH ROLLUP) as t1

UNION
SELECT COUNT(distinct user_id) as total_visitors FROM activity where 
login_time between '2018-04-12' and '2018-04-18'
ORDER BY percent_of_users desc;

我做了UNION是因为我需要获得total_visitors。

谢谢!

结果

diapason    percent_of_visitors
0-10          ...%
10+           ...%

要计算visitor_of_visitors(activity.user_id的新值/activity.user_id的旧值)。

但是我不知道如何获得旧价值。你能给我提示吗?

2 个答案:

答案 0 :(得分:1)

您正在尝试使用这种模式进行操作。

 SELECT a, b, c FROM tbl 
 UNION
 SELECT d FROM tbl

您不能那样做™。联合中的两个结果集必须具有相同的列数,并且每个结果集中的每一列都必须具有相同的数据类型。

答案 1 :(得分:1)

从工作查询开始

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.2.Final</version></dependency>

您可以在子查询中包含SELECT ifnull(t.diapason,'total') as diapason, COUNT(DISTINCT user_id) AS user_count FROM ...

total_visitors

或者,您可以使用SELECT ifnull(t.diapason,'total') as diapason, COUNT(DISTINCT user_id) * 100 / (SELECT COUNT(distinct user_id) FROM activity WHERE ...) as percent_of_users FROM (...) t GROUP BY diapason WITH ROLLUP ORDER BY percent_of_users DESC (更接近您想要的查询结构):

join

我用您的别名SELECT t1.diapason, t1.user_count * 100 / tv.total_users as percent_of_users FROM ( SELECT ifnull(t.diapason,'total') as diapason, COUNT(distinct user_id) AS user_count FROM ... ) as t1 CROSS JOIN (SELECT COUNT(distinct user_id) as total_visitors FROM activity WHERE ...) as tv ORDER BY percent_of_users DESC t1来标记查询的哪一部分属于哪里。

在这两种情况下,总计数只计算一次,但是,MySQL执行这两个查询的方式会稍有不同(尽管这不会产生太大影响)。您可能要包括对t计数的检查(并因此除以0),尽管此处不应该这样做。

备注:对于MySQL 8+,如果您使用cte,则可以稍微简化(并澄清)代码,因为您目前基本上重复两次子查询0的代码(您的实际查询一次(计算总次数),如果它比简单的a复杂,就会引起烦人和混乱。