2014-12-22 52 views
2

儘管我發現了類似於需要的東西,但我無法解決這個問題。SUM查詢的結果包含UNION ALL和CTE

所以,我會問我的例子。

(這是在延續我的上一個問題:select if there are more than n results but with conditions

我的表:

 

| TimeId | Work_Role | User_Name | 
---------------------------------- 
| 1 | users  | Oran  | 
| 2 | admin  | Ray  | 
| 3 | users  | Oran  | 
| 4 | servs  | Amit  | 
| 5 | admin  | Oran  | 
| 6 | users  | Ray  | 
| 7 | users  | Oran  | 
| 8 | servs  | Amit  | 
| 9 | admin  | Oran  | 
| 10 | users  | Oran  | 


我使用CTE來顯示USER_NAME = 「奧蘭」 和Work_Role列表=「用戶」只有在表中有2個以上時纔有效。

另外,我使用Union all來收集另一部分,它的條件是:user_name =「Oran」和Work_Role =「admin」。

結果是:

 
| TimeId | Work_Role | User_Name | 
---------------------------------- 
| 1 | users  | Oran  | 
| 3 | users  | Oran  | 
| 7 | users  | Oran  | 
| 10 | users  | Oran  | 
| 5 | admin  | Oran  | 
| 9 | admin  | Oran  | 

我的第二部分(其中有我有問題)是計算上述結果多少行了。

在這種情況下,我預計:6

我的第一個結果代碼(這是工作的罰款):

WITH CTE AS(
    SELECT *, cc = COUNT(*) OVER(PARTITION BY User_Name) FROM Table 
) 
SELECT * 
FROM CTE 
WHERE 
    Work_Role = 'users' 
    AND User_Name = 'Oran' 
    AND cc > 2 
UNION ALL 
SELECT * 
FROM TABLE 
WHERE 
    Work_Role = 'admin' 
    AND User_Name = 'Oran' 

我怎樣才能總結線號最後的結果?

使用CTE時甚至可以完成它嗎?

NOTE: 這只是一個例子。在我真正的代碼,我必須使用「UNION ALL」 :-(

10X

回答

0

首先,可以簡化查詢:

WITH CTE AS (
     SELECT t.*, cc = COUNT(*) OVER(PARTITION BY User_Name) FROM Table t 
    ) 
SELECT * 
FROM CTE 
WHERE (Work_Role = 'users' AND User_Name = 'Oran' AND cc > 2) OR 
     (Work_Role = 'admin' AND User_Name = 'Oran'); 

的好處是,這也將工作,因爲兩個子查詢具有相同列

如果你要計算的行數,只需使用select count(*)

WITH CTE AS (
     SELECT t.*, cc = COUNT(*) OVER(PARTITION BY User_Name) FROM Table t 
    ) 
SELECT COUNT(*) 
FROM CTE 
WHERE (Work_Role = 'users' AND User_Name = 'Oran' AND cc > 2) OR 
     (Work_Role = 'admin' AND User_Name = 'Oran'); 
+0

感謝名單,但我給的例子是不是真正的代碼。不幸的是,真正的代碼迫使我使用「聯合所有」而不是「或」:-( – Yael

+0

這是我的問題,迫使我使用「聯合所有」: http://stackoverflow.com/questions/27498044/i -want到返回的-同一商品,兩次在-SQL服務器 – Yael

0

好吧,最終我找到了答案,哈哈

正是基於這個問題的第一個答案:Sum a union query

  1. 我不得不別名我的派生表。
  2. 在「THIS」和「SELECT」之間設置附加選擇(使用SUM)。
  3. 更改爲每個查詢的COUNT並將其別名。

像這樣:

 
| TimeId | Work_Role | User_Name | 
---------------------------------- 
| 1 | users  | Oran  | 
| 3 | users  | Oran  | 
| 7 | users  | Oran  | 
| 10 | users  | Oran  | 
| 5 | admin  | Oran  | 
| 9 | admin  | Oran  | 

實際上,我總結的 「my_derived_table」 的 'total_lines' 列的內容:

WITH CTE AS(
    SELECT *, cc = COUNT(*) OVER(PARTITION BY User_Name) FROM Table 
) 
SELECT SUM(my_dervied_table.total_lines) FROM (
SELECT COUNT(*) as 'total_lines' 
FROM CTE 
WHERE 
    Work_Role = 'users' 
    AND User_Name = 'Oran' 
    AND cc > 2 
UNION ALL 
SELECT COUNT(*) as 'total_lines' 
FROM TABLE 
WHERE 
    Work_Role = 'admin' 
    AND User_Name = 'Oran' 
) my_dervied_table 

因此,而不是在這個輸出計數線: 4 + 2 = 6

 
    | total_lines | 
    --------------- 
1) |  4  | 
2) |  2  | 


0

shalom yael-try this code-

WITH CTE AS 

(
SELECT * 
FROM tbl 
WHERE 
    Work_Role = 'users' 
    AND User_Name = 'Oran' 
    AND (select COUNT(user_name) 
      FROM tbl 
      WHERE user_name='oran') > 2 
UNION ALL 
SELECT * 
FROM tbl 
WHERE 
    Work_Role = 'admin' 
    AND User_Name = 'Oran') 
    SELECT count([User_Name]) total_lines 
    from cte 
    GROUP BY [Work_Role],[User_Name] 
0

您是否在尋找這個,

Declare @t table(TimeId int,Work_Role varchar(50),User_Names varchar(50)) 
insert into @t values 
(1 , 'users','Oran'  ), 
( 2 ,'admin', 'Ray'), 
( 3 ,'users', 'Oran'), 
( 4,'servs', 'Amit'), 
( 5,'admin', 'Oran'), 
( 6,'users', 'Ray'), 
( 7,'users', 'Oran'), 
( 8,'servs', 'Amit'), 
( 9,'admin', 'Oran'), 
( 10,'users', 'Oran') 
;With CTE as 
(
    select *, 
    ROW_NUMBER()over(partition by User_Names,Work_Role order by timeid)rn 
    from @t 
) 
    select * from CTE where Work_Role = 'users' 
    AND User_Names = 'Oran' 
    AND exists 
    (
    select User_Names from CTE where rn>2 
    and Work_Role = 'users' AND User_Names = 'Oran' 
    ) 

UNION ALL 
    select * from CTE where Work_Role = 'admin' 
    AND User_Names = 'Oran'