使用groupBy改进我的Select(选择计数)查询

时间:2017-07-27 11:27:35

标签: sql-server tsql select count group-by

我们说我们已经拥有了这个,并希望查看尚未完成的所有任务以及另一个列,其中显示了该客户剩余的任务数量。

我的数据库中有这样的表格:

+------------+--------------------------+-------+
| CustomerID |           Task           | Done  |
+------------+--------------------------+-------+
|          1 | CleanRoom                | False |
|          1 | Cleandishes              | True  |
|          1 | WashClothes              | False |
|          2 | TakeDogsOut              | True  |
|          2 | PlayWithKids             | True  |
|          3 | HaveFunWithMrSamplesWife | True  |
|          3 | CleanMrSamplesCar        | False |
+------------+--------------------------+-------+

我需要这个作为返回表:

+------------+-------------------+-------------+
| CustomerID |       Task        | DoneOverAll |
+------------+-------------------+-------------+
|          1 | CleanRoom         | 2           |
|          1 | WashClothes       | 2           |
|          3 | CleanMrSamplesCar | 1           |
+------------+-------------------+-------------+

完美的返回表就像这样,但是当我有上面的那张时,我可以自己做到这一点:
关于这个问题;这样做可能是一个字符串组合任务。我应该在Select语句上执行此操作,还是更适合在客户端计算机上的最终应用程序中执行此操作?

+------------+-------------------+-------------+
| CustomerID |       Task        | DoneOverAll |
+------------+-------------------+-------------+
|          1 | CleanRoom         | 1/3         |
|          1 | WashClothes       | 1/3         |
|          3 | CleanMrSamplesCar | 1/2         |
+------------+-------------------+-------------+

我知道我可以像

一样
SELECT 
  a.CustomerID, 
  a.Task, 
  (
     Select count(*) from myTable where 
     customerID = a.CustomerID and 
     done = False
   ) as DoneOverAll 
 FROM myTable as a
 WHERE Done = False

但我认为这是非常无效的,因为它会为我表中的每一行执行一个Select Count。有没有办法通过JOIN使用groupBy或其他东西来实现这一目标?我还没有进入GroupBy命令。

好的,我应该先试试。拿出以下内容;

Select count(*), CustomerID from myTable group by CustomerID

我现在需要做的就是将其加入到联接中。

好的,明白了。对不起,先不要先尝试!

SELECT 
  a.CustomerID, 
  a.Task, 
  b.cnt
 FROM myTable as a
 LEFT JOIN (select count(*) AS cnt, CustomerID FROM myTable GROUP BY CustomerID) as b on a.CustomerID = B.CustomerID
 WHERE Done = False

问题留下;
完美的回归表就像这样,但是当我拥有上面那张时,我可以自己做到这一点:
关于这个问题;这样做可能是一个字符串组合任务。我应该在Select语句上执行此操作,还是更适合在客户端计算机上的最终应用程序中执行此操作?

+------------+-------------------+-------------+
| CustomerID |       Task        | DoneOverAll |
+------------+-------------------+-------------+
|          1 | CleanRoom         | 1/3         |
|          1 | WashClothes       | 1/3         |
|          3 | CleanMrSamplesCar | 1/2         |
+------------+-------------------+-------------+

2 个答案:

答案 0 :(得分:1)

我不确定为什么Done = False,但这是你的逻辑。 : - )

如果没有LEFT JOIN,我会做什么。

    SELECT 
      a.CustomerID, 
      a.Task, 
      SUM(CASE WHEN a.Done = 'False' THEN 1 ELSE 0 END) DoneOverAll,
      SUM(Case WHEN a.Done = 'True' THEN 1 ELSE 0 END) NotDone
     FROM myTable as a 
     Group By a.CustomerID, a.Task

答案 1 :(得分:0)

单独计算。

     ;with tempfalse as(

              SELECT 
                  a.CustomerID, 
                  a.Task, 
                  count(*) as DoneOverAll 
             FROM myTable as a
             WHERE Done = False
             group by a.CustomerID,   a.Task
     )

    , temptrue (
           SELECT 
               a.CustomerID, 
               a.Task, 
               count(*) as total 
         FROM myTable as a
         group by a.CustomerID,  a.Task
     )

         SELECT 
           a.CustomerID, 
           a.Task, 
           cast(NULLIF(DoneOverAll,0) as varchar (10) ) + '/' +  cast(NULLIF(b.total,0) as varchar (10) )
             from temptrue as a left join tempfalse b 
           on  a.CustomerID =a.CustomerID and  
           a.Task = b.Task