2015-01-23 2 views
0

Я пытаюсь написать подзапрос в представлении, которое будет возвращено в виде столбца, но я не совсем уверен, что даст мне самый эффективный вызов. У меня есть View A, который собирает кучу полей из разных таблиц (одна таблица имеет Listings, которая имеет отношение 1 к многим с OpenHours), тогда одно из полей, которое я хочу, чтобы оно было из другой таблицы (OpenHours), которая будет только Сегодняшнее поле открытых часов.TSQL Subquery effeciency

Таблица OpenHours имеет ListingID, Day (0 основанный на день недели), часы (текст часы работы, такие как «8:00 am-5:00pm»). Вот то, что мне нужно сделать:

  1. Проверьте OpenTable есть запись для этого конкретного списка, который day = 7, если его 7 (что не день недели), а затем вернуться «Открыто 24 часа».
  2. Если не существует, то возвращает следующую запись, так как сервера SQL datepart(dw.. в 1 на основе, следующий будет использоваться выберите datepart(dw,getdate())-1, чтобы получить на основе день недели, начиная с 0 дня в воскресенье (воскресенье не будучи 0)
  3. Возврата ничего, если нет записей, соответствующих критериям.

Я был бы признателен за помощь в этом. Я попытался написать это, но не мог уйти далеко. Я не уверен, как объявлять переменные для дня недели в представлении.

ОБНОВЛЕНИЕ вот моя функция, кто-нибудь видит какие-либо вопиющие неэффективности?

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 

ОБНОВЛЕНО VIEW

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 (ОТ листингах л)

I upadted мнение (добавлен FROM) в операторы выбора

Я предпочитаю не использовать функцию, потому что мне нужно было добавить индекс в таблицу opentime на листинге и день, чтобы сделать его немного быстрее, но если добавление sql в представление было бы лучше, это было бы замечательно

+2

сделать некоторые запросы и проверки планов выполнения и статистики для запроса. Затем вы можете определить, какой маршрут лучше всего в вашем случае. Это может очень сильно отличаться от ситуации к ситуации, поэтому единственный путь - исследовать. –

+0

Вы не можете объявлять переменные в представлении. Представление не является логикой программирования. Если вам действительно нужна помощь, вам нужно предоставить некоторые детали. –

+0

обновил исходный код – Zoinky

ответ

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 
+0

Обновил исходное сообщение, мне пришлось добавить FROM в ur select, но все равно получить синтаксическую ошибку, был опубликован код для моего представления – Zoinky