SQL Query +更有效的替代方案

时间:2011-11-23 06:32:32

标签: sql sql-server

我的查询涉及SQL Server中的2个表'Coupons'和'CouponUsedLog',下面的查询将从这两个表中获取一些信息供统计学习使用。不知怎的,我觉得虽然我的查询有效并且返回了我想要的结果,但我觉得我可以用更有效的方式编写,如果有更好的方法可以重写这个,有人可以请一下吗?我使用了太多不必要的变量和连接吗?感谢。

DECLARE @CouponISSUED        int=null
DECLARE @CouponUSED          int=null
DECLARE @CouponAVAILABLE     int=null
DECLARE @CouponEXPIRED       int=null
DECLARE @CouponLastUsed      Date=null


--Total CouponIssued
SET    @CouponISSUED = 
(
    select count(*) 

    from   Coupon C Left Join 
           couponusedlog CU on C.autoid = CU.Coupon_AutoID

    where  C.VoidedBy is null and 
           C.VoidedOn is null and 
           DeletedBy  is null and 
           DeletedOn  is null and 
           Card_AutoID in (Select AutoID 
                           from   Card 
                           where  MemberID = 'Mem001')
)

--Total CouponUsed
SET @CouponUSED = 
(
    select count(*) 
    from   couponusedlog CU Left Join 
           Coupon C on CU.Coupon_AutoID = V.autoid

    where  CU.VoidedBy is null and 
           CU.VoidedOn is null and 
           C.Card_AutoID in (select AutoID 
                             from   Card 
                             where  MemberID = 'Mem001')
)


SET @CouponAVAILABLE = @CouponISSUED - @CouponUSED


--Expired Coupons
SET @CouponEXPIRED = 
(
    select Count(*) 

    from   Coupon C Left Join 
           couponusedlog CU on C.autoid = CU.Coupon_AutoID

    where  C.VoidedBy is null and 
           C.VoidedOn is null and 
           deletedBy  is null and 
           deletedOn  is null and
           Card_AutoID in (select AutoID 
                           from  Card 
                           where MemberID = 'Mem002') and
           CONVERT (date, getdate()) > C.expirydate
) 

--Last Used On
SET @CouponLastUsed = 
(
    select CONVERT(varchar(10), 
           Max(VU.AddedOn), 103) AS [DD/MM/YYYY] 

    from   couponusedlog CU Left Join 
           coupon C on CU.Coupon_AutoID = C.autoid

    where  CU.voidedBy is null and 
           CU.voidedOn is null and 
           C.Card_AutoID in (select AutoID 
                             from Card 
                             where MemberID = 'Mem002')
)



Select  @CouponISSUED    As Coupon_Issued,
        @CouponUSED      As Coupon_Used, 
        @CouponAVAILABLE As Coupon_Available,
        @CouponEXPIRED   As Coupon_Expired,
        @CouponLastUsed  As Last_Coupon_UsedOn

2 个答案:

答案 0 :(得分:1)

一般情况下,如果您只是在四个单独的查询中查找几乎相同的数据集,那么在单个查询中执行操作会更好。

此查询通过将WHERE子句转换为CASE语句的SUMS,将您需要的内容组合到一个查询中。当您进行计数或总和时,日期的最大值是您可以做的正常事情。

SELECT COUNT(*) couponissued, 
       SUM(CASE 
             WHEN deletedby IS NULL 
                  AND deletedon IS NULL THEN 1 
             ELSE 0 
           END) AS couponused, 
       SUM(CASE 
             WHEN deletedby IS NULL 
                  AND deletedon IS NULL 
                  AND Getdate() > c.expirydate THEN 1 
             ELSE 0 
           END) AS couponex,
 MAX(vu.addedon) CouponEXPIRED 
FROM   [couponusedlog] cu 
       LEFT JOIN [Coupon] c 
         ON ( cu.coupon_autoid = v.autoid ) 
WHERE  cu.voidedby IS NULL 
       AND cu.voidedon IS NULL 
       AND ( c.card_autoid IN (SELECT [AutoID] 
                               FROM   [Card] 
                               WHERE  memberid = 'Mem001') ) 

然后,您可以将其转换为公用表格式进行减法和格式化

答案 1 :(得分:0)

您是否主动要求尽可能有效,或者因为您想要纠正的实际性能问题?您可以以更难以管理的代码为代价来提高效率。如果现在表现还可以,我强烈建议你离开它,因为下一个人会很好地理解它。如果你从中做出一个巨大而有效的乱码sql语句,那么当你或其他任何人想要更新它的某些内容时,当你试图重新弄清楚你在写什么时,你会花费3倍的时间它