T SQL子查询效率

时间:2015-01-23 14:53:53

标签: sql-server tsql

我正在尝试在视图中编写子查询以作为列返回,但我不确定什么会给我最有效的调用。 我有一个View A,它从不同的表中收集了一堆字段(一个表ListingsOpenHours有1对多的关系)然后我希望它来自另一个表的一个字段(OpenHours)只会是今天的开放时间字段。

OpenHours表格有ListingIDDay(0表示星期几),小时(开放时间的文字,例如"上午8点 - 5:00 pm")。这是我需要做的:

  1. 检查OpenTable是否有day = 7特定列表的记录,如果其为7(不是一周中的某一天),则返回" 24小时开放"。
  2. 如果不存在,则返回下一条记录,因为SQL Server datepart(dw..基于1,以下将使用select datepart(dw,getdate())-1来获取从星期日(星期日)开始的0天基础日0)
  3. 如果没有符合条件的记录,则不返回任何内容。
  4. 我希望得到一些帮助。我试图写这个,但无法走远。我不确定如何在视图中声明星期几的变量。

    更新 这是我的功能,任何人都看到任何明显的低效率?

    ALTER FUNCTION [dbo].[GetTodaysOpenHours](@ListingID int) 
    RETURNS VARCHAR(50)
    AS
    BEGIN
    DECLARE @DayOfWeek int
    --SQL Day of week starts on sunday but it is 1 based, listing open hours are 0 based
    SET @DayOfWeek = DATEPART(DW, GETDATE()) - 1
    DECLARE @OpenHours VARCHAR(50)
    IF EXISTS(SELECT * FROM OpenHours WHERE Day = 7 AND ListingID = @ListingID) 
        SET @OpenHours = 'Open 24 Hours'
    ELSE    
        SELECT @OpenHours  =  Hours FROM OpenHours WHERE ListingID = @ListingID AND Day = @DayOfWeek    
    
    RETURN @OpenHours
    END
    

    更新后的视图

    ALTER view [dbo].[vListings]
    as
    SELECT  l.ListingID, l.ExpiryDate, l.IsApproved, l.IsActive,      l.Position,MoneyField1, DateField1, 
        IntField1, IntField2, IntField3, IntField4, 
        BoolField1, BoolField2, BoolField3,  
        OptionField1, OptionField2, OptionField3, OptionField4, 
        IsTop, TopStartDate, TopExpireDate, Address, Address + ' ' + c.Name + ' ' + p.Name AS FullAddress, 
        o1.Description as Options1Description,
        o2.Description as Options2Description,
        o3.Description as Options3Description,
        o4.Description as Options4Description, 
        COALESCE(
                  (SELECT TOP 1 ThumbnailPath
                   FROM Attachments
                   WHERE ListingID = l.listingID), '/content/images/noImageThumbnail2.jpg') AS MainThumbnail,
                   COALESCE(
                  (SELECT TOP 1 ThumbnailPath2
                   FROM Attachments
                   WHERE ListingID = l.listingID), '/content/images/noImageThumbnail.jpg') AS MainThumbnail2,
        l.UserID,
        c.SubDomainName as CitySubDomainName, l.Name,
        CASE 
            WHEN l.IsAutoGenerated = 1  THEN l.ImportedPhoneNumber
            ELSE  dbo.FormatPhoneNumber(u.PhoneNumber)
        END as PhoneNumber,
        CASE 
            WHEN l.IsAutoGenerated = 1  THEN l.ImportedContactInfo
            ELSE  u.FirstName + ' ' + u.LastName
        END as ContractInfo,
        p.Abbv as StateAbbv,
        cn.Code as CountryCode,
        l.Comments, l.UniqueID, l.Rating, l.Website, 
        (select    L.ListingID,
    isnull(H1.Hours, H2.Hours) as Hours
    from Listings L
        outer apply (
            select Hours FROM OpenHours H WHERE H.Day = 7 
            AND H.ListingID = L.ListingID
        ) H1
         outer apply (
            select Hours FROM OpenHours H WHERE Day = DATEPART(DW, GETDATE()) - 1
            AND H.ListingID = L.ListingID
        ) H2
            --dbo.GetTodaysOpenHours(l.ListingID) as TodaysOpenHours
    
    
    FROM Listings l
        INNER JOIN Cities c ON c.CityID = l.CITYID
        INNER JOIN Provinces p ON p.ProvinceID = c.ProvinceID
        INNER JOIN Countries cn ON cn.CountryID = p.CountryID
        INNER JOIN AspNetUsers u ON u.Id = l.UserID
        LEFT OUTER JOIN Options1 o1 ON o1.OptionID = l.OptionField1
        LEFT OUTER JOIN Options2 o2 ON o2.OptionID = l.OptionField2
        LEFT OUTER JOIN Options3 o3 ON o3.OptionID = l.OptionField3
        LEFT OUTER JOIN Options4 o4 ON o4.OptionID = l.OptionField4
    

    GO

    我收到一条错误,指出"关键字FROM附近的语法不正确 (来自清单l)

    我还将视图(添加了FROM)添加到了select语句中

    我不喜欢使用它的功能,因为我必须在listingid和day上为我的openhours表添加一个索引,以便使它更快一点但是如果将sql添加到视图本身会更好,那将是很棒的

1 个答案:

答案 0 :(得分:0)

用户定义的功能通常不是性能最佳的解决方案。您可以尝试通过执行此类操作将该SQL添加到视图/查询中(抱歉,无法对此进行测试,希望没有语法错误):

select
    L.ListingID,
    isnull(H1.Hours, H2.Hours) as Hours
from Listing L
    outer apply (
        select Hours OpenHours H WHERE H.Day = 7 
        AND H.ListingID = L.ListingID
    ) H1
     outer apply (
        select Hours OpenHours H WHERE Day = DATEPART(DW, GETDATE()) - 1
        AND H.ListingID = L.ListingID
    ) H2