我有一个SQL查询,我想优化它作为SP的内部查询。
SELECT TOP 1 @CurrentStartDate = Strt_Dt FROM (
SELECT 1 AS seq, Stat, Strt_Dt, Est_Hrs_Comp, EndDate, Tckt_Id, Envr
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID AND stat = 'INPR'
UNION
SELECT TOP 1 2 AS seq, Stat, Strt_Dt, Est_Hrs_Comp, EndDate, Tckt_Id, Envr
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID AND stat = 'CMPL'
ORDER BY enddate DESC
UNION
SELECT TOP 1 3 AS seq, Stat, Strt_Dt, Est_Hrs_Comp, EndDate, Tckt_Id, Envr
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID AND stat = 'PLND'
ORDER BY strt_dt
UNION
SELECT 4 AS seq, 'UNP', NULL, NULL, NULL, tckt_id, 'Unplanned'
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID
) aa
ORDER BY aa.seq
有没有更好的方法来使用此查询。我需要这个,因为我有很多相同类型的逻辑。
答案 0 :(得分:2)
对于相同的标准,您正在对来自同一个表的4个结果进行联合,您是否可以只使用CASE语句? e.g。
SELECT
CASE Stat
WHEN 'INPR' THEN 1
WHEN 'CMPL' THEN 2
WHEN 'PLND' THEN 3
WHEN 'Unplanned' THEN 4
ELSE 0 -- Not sure what your 'ELSE' case would be
END as Seq,
etc....
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID
对于具有逻辑的所有字段,您仍然需要case语句,但它将包含所有数据,并且将更容易阅读。性能也应该好很多。
答案 1 :(得分:2)
SELECT TOP 1 @CurrentStartDate = Strt_Dt FROM (
SELECT
CASE stat WHEN 'INPR' THEN 1
WHEN 'CMPL' THEN 2
WHEN 'PLND' THEN 3
ELSE 4 END AS seq ,
Stat, Strt_Dt, Est_Hrs_Comp, EndDate, Tckt_Id, Envr
FROM pipeline_rest_envr_info e
WHERE e.tckt_id = @TicketID ) aa
ORDER BY aa.seq
实际上它与@Charleh
的答案相同你不需要第二个和第三个TOP 1
,因为你只选择了所有联盟中的第一个
答案 2 :(得分:2)
我没有回复我的评论,我会做出一些假设......
单个tckt_id
可以:
CMPL
项。 (完成?) INPR
项。 (进行中?) PLND
项。 (计划?)
你想要strt_dt
的......
INPR
项(如果存在)。 CMPL
项目(如果存在)。 PLND
项目(如果存在)。 NULL
SELECT
TOP 1
@current_start_date
=
CASE WHEN stat = 'INPR' THEN MIN(strt_dt)
WHEN stat = 'CMPL' THEN MAX(strt_dt)
WHEN stat = 'PLND' THEN MIN(strt_dt)
ELSE NULL
END
FROM
pipeline_rest_envr_info
WHERE
tckt_id = @TicketID
GROUP BY
stat
ORDER BY
CASE WHEN stat = 'INPR' THEN 1
WHEN stat = 'CMPL' THEN 2
WHEN stat = 'PLND' THEN 3
ELSE 4 END
这还有一个额外的假设:
CMPL
项目,也是最后一次如果该假设是错误的,并且您可以访问ROW_NUMBER()
,那么您可以尝试这样做......
WITH
plus_sort_order
(
SELECT
ROW_NUMBER() OVER (PARTITION BY stat ORDER BY strt_dt ASC ) AS order_strt,
ROW_NUMBER() OVER (PARTITION BY stat ORDER BY end_dt DESC) AS order_end,
*
FROM
pipeline_rest_envr_info
WHERE
tckt_id = @TicketID
)
SELECT
TOP 1
@current_start_date = strt_dt
FROM
plus_sort_order
WHERE
(order_strt = 1) OR (stat = 'CMPL' AND order_end = 1)
ORDER BY
CASE WHEN stat = 'INPR' THEN 1
WHEN stat = 'CMPL' THEN 2
WHEN stat = 'PLND' THEN 3
ELSE 4 END
还有很多其他方法。但很大程度上取决于您的数据。我建议你在这里和其他答案中使用这些想法,并使用解释/查询计划来确定每个可用选项所需的索引。
答案 3 :(得分:0)
我认为你应该根据需要制作Temp Table
索引,然后从每个UNION
中插入记录。
这比使用UNION
s更快。