2016-08-12 28 views
0

表 -计算脚麻由于加入问题

+----+-----------+-----------+---------+---------------------+------------+ 
| ID | Client_Id | Driver_Id | City_Id |  Status  | Request_at | 
+----+-----------+-----------+---------+---------------------+------------+ 
| 1 |   1 |  10 |  1 | completed   | 2013-10-01 | 
| 2 |   2 |  11 |  1 | cancelled_by_driver | 2013-10-01 | 
| 3 |   3 |  12 |  6 | completed   | 2013-10-01 | 
| 4 |   4 |  13 |  6 | cancelled_by_client | 2013-10-01 | 
| 5 |   1 |  10 |  1 | completed   | 2013-10-02 | 
| 6 |   2 |  11 |  6 | completed   | 2013-10-02 | 
| 7 |   3 |  12 |  6 | completed   | 2013-10-02 | 
| 8 |   2 |  12 |  12 | completed   | 2013-10-03 | 
| 9 |   3 |  10 |  12 | completed   | 2013-10-03 | 
| 10 |   4 |  13 |  12 | cancelled_by_driver | 2013-10-03 | 
+----+-----------+-----------+---------+---------------------+------------+ 

我尝试 -

WITH src 
    AS (SELECT Count(status) AS Denom, 
       request_at 
     FROM trips 
     WHERE status = 'completed' 
     GROUP BY request_at), 
    src2 
    AS (SELECT Count(status) AS Num, 
       request_at 
     FROM trips 
     WHERE status <> 'completed' 
     GROUP BY request_at) 
SELECT Cast(Count(num) AS FLOAT)/Cast(Count(Denom) AS FLOAT) AS cancel_rate, 
     trips.request_at 
FROM src, 
     src2, 
     trips 
GROUP BY trips.request_at; 

我试图找到每天的取消率,但它正在清除错误( MY OUTPUT) -

+-------------+------------+ 
| cancel_rate | request_at | 
+-------------+------------+ 
|   24 | 2013-10-01 | 
|   18 | 2013-10-02 | 
|   18 | 2013-10-03 | 
+-------------+------------+ 

2013-10-01的取消费率应为0.5而非24.与其他日期类似,它应该不同。

我知道问题出在这一部分,但我不知道什么是正确的方法或如何处理它

SELECT Cast(Count(num) AS FLOAT)/Cast(Count(Denom) AS FLOAT) AS cancel_rate, 
     trips.request_at 
FROM src, 
     src2, 
     trips 

有没有什么办法可以把超过1个select语句中With NAME as()条款?这样我就不会使用任何JOIN或多个表。

+0

我想解决的两个步骤。从cte开始,只需要一个。做'总结'(当状态='完成',然后状态结束)作为Denom'等 – jarlh

+0

你根本不需要CTE。你只需要一个case语句来使分子1或0取决于状态,如下所示:'CASE当状态LIKE'取消%'THEN 1 ELSE 0 END作为分子' –

回答

1

使用条件汇总:

SELECT SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as denom, 
     SUM(CASE WHEN status <> 'completed' THEN 1 ELSE 0 END) as num, 
     AVG(CASE WHEN status <> 'completed' THEN 1.0 ELSE 0 END) as cancel_rate 
FROM trips 
GROUP BY request_at; 

注意计算为cancel_rate。使用AVG()而不是将这两个值分开比较简单。使用1.0是因为SQL Server执行整数运算,所以1/2是0而不是0.5。

+0

感谢提及'1.0'部分。我也尝试类似的事情,但结果是0,这就是为什么我采取当前的做法! –

+1

你的公式中有一个'''太多了,'AVG'不会计算出与'num/denom'相同的值。 – cars10m

+0

@ cars10这是我猜想的错字。删除它效果不错 –

0

OK,有些又迟到,但这里是另一种变体(编辑):

SELECT SUM(CASE LEFT(status,9) WHEN 'cancelled' THEN 1. ELSE 0 END) 
     /COUNT(*) cancellation_rate, 
     request_at 
FROM trips GROUP BY request_at ORDER BY request_at 
+0

2013-10-01的取消率将出现1你的代码 –

+0

那么,我看到它的方式:那天所有已完成的预订都被取消了,所以1.0将是正确的值。 – cars10m

+0

在2013-10-01,共有4个游乐设施,其中2个已完成,另外两个被取消。因此0.5是取消率。 :) –