案例/何时以及如何在cte中使用完全相同的查询 [英] Case/when and how to use exactly the query in cte

查看:65
本文介绍了案例/何时以及如何在cte中使用完全相同的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

- 有两张桌子



- 从请求中选择*

--There are two tables

--select * from request

hub_id	totalrequest
9	45
20	55
136	75







select * from route_header
<pre>
action1 routid  hub_id  occ
p        1       9       4
p        2       9       3
p        3       9       2
d        4       9       4
d        5       9       1
p        6       20      3
p        7       20      3
p        8       20      4
p        9       20      4
d       10       20      5
p       11      136      2
p       12      136      1
d       13      136      5
d       14      136      3
d       15      136      4
</pre>




--------------------- o / p我想要的---------------- -----------



---------------------o/p which i want ---------------------------

hub  totalrequest    totalroutes totalemployee Realoccupancy  pickcount  dropcount
9	   45	         5	      14	      2          3           2
20	   55	         5	      19	      3          4           1
136	   75	         5	      15	      3          2           3



-------------------- --------------------------------------------



- 我想在不使用光标/ while循环的情况下以基于集合的方式进行。



- 我有什么到目前为止尝试了






----------------------------------------------------------------

-- I want to do it in a set based way without using cursor/while loop.

--what i have tried so far


;with cte(hub,totalrequest,totalroutes,totalemployee) as
(
select
rd.hub_id,
r.totalrequest,
count(rd.routid) as Totalroutes
,sum(occ) as totalemployee
from request r
join route_header rd on r.hub_id=rd.hub_id
group by
rd.hub_id,
r.totalrequest
),
cte1 as
(
select hub,
totalrequest,
totalroutes,
totalemployee,
floor(totalemployee/totalroutes) as Realoccupancy from  cte
)
select * from cte1







-----------------------------------------------------------------------------
--where i stuck is (till realoccupancy everything is fine) 
-->>but pickcount and dropcount i am unable to do it

--i was trying to use case when ...but failed to do it.
--just after this statement in cte
,sum(occ) as totalemployee

i have to write the logic to get the pickcount and dropcount in cte...and then i will fetch in cte1.

--tell me the way

-------------------------------------------------------------------------------
if you have other solution also help me.

推荐答案

Christian Graus的Solution1非常好。除此之外,我想提供另一种方式 - 使用子查询。看看例子:

Solution1 by Christian Graus is very good. In addition to it i'd like to provide another way - using subqueries. Have a look at example:
CREATE TABLE #request (hub_id  INT, totalrequest INT)

INSERT INTO #request (hub_id, totalrequest)
VALUES(9, 45),
(20, 55),
(136, 75)

CREATE TABLE #route_header (action1 VARCHAR(30), routid INT,  hub_id  INT, occ INT)

INSERT INTO #route_header (action1, routid , hub_id,  occ)
VALUES('p', 1, 9, 4),
('p', 2, 9, 3),
('p', 3, 9, 2),
('d', 4, 9, 4),
('d', 5, 9, 1),
('p', 6, 20, 3),
('p', 7, 20, 3),
('p', 8, 20, 4),
('p', 9, 20, 4),
('d', 10, 20, 5),
('p', 11, 136, 2),
('p', 12, 136, 1),
('d', 13, 136, 5),
('d', 14, 136, 3),
('d', 15, 136, 4)

SELECT t1.hub_id, t1.totalrequest , t1.Totalroutes, t1.TotalEmployee, FLOOR(t1.TotalEmployee / t1.Totalroutes) AS RealOccupancy,
    (SELECT COUNT(action1) FROM #route_header WHERE action1 = 'p' AND hub_id = t1.hub_id) AS PickCount,
    (SELECT COUNT(action1) FROM #route_header WHERE action1 = 'd' AND hub_id = t1.hub_id) AS DropCount
FROM (
    SELECT r.hub_id, r.totalrequest, COUNT(rh.routid) AS Totalroutes, SUM(rh.occ) AS TotalEmployee
    FROM #request AS r INNER JOIN  #route_header AS rh ON r.hub_id = rh.hub_id
    GROUP BY r.hub_id, r.totalrequest
    ) AS t1


DROP TABLE #request
DROP TABLE #route_header





结果(按预期):



Result (as expected):

hub_id  to.req. to.rou. to.emp. Re.Occ. PickCo. DropCo.
9	45	5	14	2	3	2
20	55	5	19	3	4	1
136	75	5	15	3	2	3


为您想要的每个组创建一个CTE。创建一个试图分组三件事的选择太难了。我还会创建不互相引用的CTE,如果可以的话,只需在最终的SQL中加入结果表。它更具可读性。创建SQL以创建标量值列表,使用SQL创建三个计算值。然后在最后的SQL语句中加入所有四个表来获得结果。





因为你给了我们你的数据,我能够创建表和解决方案:



Create a CTE for each group you want. Creating one select that tries to group on three things is too hard. I would also create CTEs that don't reference each other, and just join the resultant tables in my final SQL, if I could. It's just more readable that way. Create SQL to create your list of scalar values, and SQL to get your three calculated values. Then join all four tables in your final SQL statement to get your result.


Because you gave us your data, I was able to create your tables and a solution:

;with root(hubid,totalrequest,totalroutes,totalemployee) as
(
select
rd.hub_id,
r.totalrequest,
count(rd.routid) as Totalroutes
,sum(occ) as totalemployee
from request r
join route_header rd on r.hub_id=rd.hub_id
group by
rd.hub_id,
r.totalrequest
),
totals(hubId, pickCount,dropCount) as
(
select hub_id,
sum(CASE WHEN action1 = 'p' THEN 1 ELSE 0 end) AS pickcount,
sum(CASE WHEN action1 = 'd' THEN 1 ELSE 0 end) AS dropcount
FROM route_header
GROUP BY hub_id
)

select r.*, floor(totalemployee/totalroutes) as Realoccupancy, pickCount, dropCount from root r INNER JOIN totals t ON r.hubid = t.hubid





请注意,我让每个CTE对解决方案的一部分负责,我移动了一些计算到最终的SQL。我的目标是让每个部分都有一个明确的任务,并且整体易于维护。



Note that I made each CTE responsible for one part of the solution and I moved some of the calculation to the final SQL. My goal was for each part to have a clear task, and for the whole to be easily maintained.


这篇关于案例/何时以及如何在cte中使用完全相同的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆