有没有办法简化下面的查询?我得到了我想要的但我想学习如何通过使用更短的查询来实现结果。至于结果,我可以将值NULL替换为0吗?
SELECT ad.Staff, ad.TYear, ad.TWeek, b.TMonth FROM (SELECT a.Staff, a.TYear, d.TWeek FROM (SELECT t2.creatorfullname AS Staff, count(distinct(t1.ticketmaskid)) AS TYear FROM swtickets t1 JOIN swticketauditlogs t2 ON t1.ticketid = t2.ticketid WHERE (YEAR(from_unixtime(t2.dateline)) = YEAR(CURRENT_TIMESTAMP) AND FIND_IN_SET (t2.creatorfullname,'Andy Murray,Rafael Nadal,Maria Sharapova') > 0 AND t2.actionmsg LIKE '%Ticket status changed from: % to: Closed%') AND totalreplies > 0 GROUP BY t2.creatorfullname) AS a LEFT OUTER JOIN (SELECT t2.creatorfullname AS Staff, count(distinct(t1.ticketmaskid)) AS TWeek FROM swtickets t1 JOIN swticketauditlogs t2 ON t1.ticketid = t2.ticketid WHERE (WEEK(from_unixtime(t2.dateline)) = WEEK(CURRENT_TIMESTAMP) AND FIND_IN_SET (t2.creatorfullname,'Andy Murray,Rafael Nadal,Maria Sharapova') > 0 AND t2.actionmsg LIKE '%Ticket status changed from: % to: Closed%') AND totalreplies > 0 GROUP BY t2.creatorfullname) AS d ON (a.Staff = d.Staff)) AS ad LEFT OUTER JOIN (SELECT t2.creatorfullname AS Staff, count(distinct(t1.ticketmaskid)) AS TMonth FROM swtickets t1 JOIN swticketauditlogs t2 ON t1.ticketid = t2.ticketid WHERE (MONTH(from_unixtime(t2.dateline)) = MONTH(CURRENT_TIMESTAMP) AND FIND_IN_SET (t2.creatorfullname,'Andy Murray,Rafael Nadal,Maria Sharapova') > 0 AND t2.actionmsg LIKE '%Ticket status changed from: % to: Closed%') AND totalreplies > 0 GROUP BY t2.creatorfullname) AS b ON (ad.Staff = b.Staff);
+----------------+-------+-------+--------+ | Staff | TYear | TWeek | TMonth | +----------------+-------+-------+--------+ | Andy Murray | 337 | 37 | 142 | | Rafael Nadal | 49 | NULL | 13 | | Maria Sharapova| 49 | 1 | 4 | +----------------+-------+-------+--------+
答案 0 :(得分:1)
尝试:
SELECT t2.creatorfullname AS Staff,
count(distinct case when YEAR(from_unixtime(t2.dateline)) = YEAR(CURRENT_TIMESTAMP)
then t1.ticketmaskid end) AS TYear,
count(distinct case when WEEK(from_unixtime(t2.dateline)) = WEEK(CURRENT_TIMESTAMP)
then t1.ticketmaskid end) AS TWeek,
count(distinct case when MONTH(from_unixtime(t2.dateline)) = MONTH(CURRENT_TIMESTAMP)
then t1.ticketmaskid end) AS TMonth
FROM swtickets t1
JOIN swticketauditlogs t2
ON t1.ticketid = t2.ticketid
WHERE FIND_IN_SET (t2.creatorfullname,'Andy Murray,Rafael Nadal,Maria Sharapova') > 0
AND t2.actionmsg LIKE '%Ticket status changed from: % to: Closed%'
AND totalreplies > 0
GROUP BY t2.creatorfullname
- 编辑 -
当我们需要计算满足许多条件的记录时,可以使用这种方法
在这种方法中,我们使用最简单的案例表达式形式:
CASE WHEN condition THEN expression1 [ ELSE expression2 ] END
case表达式的作用类似于IF
语句 - 它计算条件,当条件为真时,则返回第一个表达式的结果,否则返回第二个表达式的结果,或者 - 当没有给出第二个表达式时({ {1}}部分被跳过) - 它返回else
MySql有一个IF函数:NULL
,其作用方式与case表达式相同,但case表达式是ANSII SQL Standard的一部分,由大多数数据库实现,而IF(expr1,expr2,expr3)
函数是MySql的专有扩展。登记/>
请查看此链接了解详情:https://dev.mysql.com/doc/refman/5.6/en/control-flow-functions.html
计数记录的查询可能看起来像:
IF
SELECT count(*),
count( some_column ),
count( CASE WHEN condition1 THEN 1 END ),
count( IF( condition2, 1, null ) ),
sum( CASE WHEN condition3 THEN 1 ELSE 0 END ),
count( DISTINCT CASE WHEN condition4 THEN some_column END ),
count( DISTINCT IF( condition2, 1, some_column ) )
FROM sometable
- 计算总行数
COUNT(*)
- 当COUNT( expression )
不为空(它跳过空值)时计算多个行
expression
- 与上述相同,但仅考虑不同的值
COUNT( DISTINCT expression )
- 对于每一行,它评估count( DISTINCT CASE WHEN condition THEN some_column END )
并在条件为真时返回值condition
,否则返回null。由于跳过了空值,因此它只计算满足条件的行的不同值。