Запросы с использованием табличного параметра - PullRequest
2 голосов
/ 22 декабря 2010

Мне нужна помощь, пожалуйста, при написании sproc, он принимает табличный параметр @Locations, тип которого определяется следующим образом:

CREATE TYPE [dbo].[tvpLocation] AS TABLE(
    [CountryId] [int] NULL,
    [ResortName] [nvarchar](100) NULL,
    [Ordinal] [int] NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [Ordinal] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)

@ Местоположение будет содержать как минимум 1 строку.Каждая строка будет иметь ненулевой CountryId, и МОЖЕТ иметь ненулевое имя ResortName.Каждая строка будет иметь уникальный Порядковый номер, первый из которых равен 0. Комбинации CountryId и ResortName в @Locations будут уникальными.

Спрок должен выполнить поиск по следующей структуре таблицы.

alt text

Изображение можно увидеть лучше, если щелкнуть его правой кнопкой мыши и просмотреть изображение, или аналогичное, в зависимости от вашего браузера.

Теперь я застрял, sproc должен быть в состояниидля поиска туров, где:

  • 1-й тур-отель Tour (Ordinal 0) имеет тот же CountryId (и ResortName, если указан), что и в 1-й строке @Locations (Ordinal 0).
  • А также, если @Locations имеет> 1 строку, Тур должен иметь дополнительные TourHotels, ВСЕ из которых должны быть в оставшихся CountryIds (и ResortNames, если указано) из этих оставшихся строк @Locations.

Edit Это код, который я наконец-то использовал, основываясь на предложении Энтони Фаулла.Большое спасибо Энтони:

select distinct T.Id
from tblTour T
join tblTourHotel TH on TH.TourId = T.Id
join tblHotel H ON H.Id = TH.HotelId
JOIN @Locations L ON
    (
        (
            L.Ordinal = 0
            AND TH.Ordinal = 0
        )
        OR
        (
            L.Ordinal > 0
            AND TH.Ordinal > 0
        )
    )
    AND L.CountryId = H.CountryId
    AND
    (
        L.ResortName = H.ResortName
        OR L.ResortName IS NULL
    )
cross apply( select COUNT(TH2.Id) AS [Count] FROM tblTourHotel TH2 where TH2.TourId = TH.TourId ) TourHotelCount
where
TourHotelCount.[Count] = @LocationCount
group by T.Id, T.TourRef, T.Description, T.DepartureDate, T.NumNights, T.DepartureAirportId, T.DestinationAirportId, T.AirlineId, T.FEPrice
having COUNT(distinct TH.Id) = @LocationCount

Ответы [ 2 ]

1 голос
/ 24 декабря 2010
WITH Matches AS
(
    SELECT TH.TourId, TH.Ordinal
    FROM dbo.tblTourHotel TH
    WHERE EXISTS
    (
        SELECT 1
        FROM dbo.tblHotel H
        JOIN @Locations L ON
            (
                (
                    L.Ordinal = 0
                    AND TH.Ordinal = 0
                )
                OR
                (
                    L.Ordinal > 0
                    AND TH.Ordinal > 0
                )
            )
            AND L.CountryId = H.CountryId
            AND
            (
                L.ResortName = H.ResortName
                OR L.ResortName IS NULL
            )
        WHERE H.Id = TH.HotelId
    )
)
SELECT M.TourId
FROM Matches M
WHERE
(
    NOT EXISTS
    (
        SELECT 1
        FROM @Locations L
        WHERE L.Ordinal > 0
    )
    OR NOT EXISTS
    (
        SELECT 1
        FROM dbo.tblTourHotel TH
        WHERE TH.Ordinal > 0
        AND NOT EXISTS
        (
            SELECT 1
            FROM Matches M
            WHERE M.Ordinal = TH.Ordinal
            AND M.TourId = TH.TourId
        )
    )
)
WHERE M.Ordinal = 0
0 голосов
/ 22 декабря 2010
SELECT TH.TourId
FROM dbo.tblTourHotel TH
JOIN dbo.tblHotel H on H.Id = TH.HotelId
LEFT JOIN @Locations L
    ON SIGN(L.Ordinal) = SIGN(TH.Ordinal) 
    AND L.CountryId = H.CountryId 
    AND (L.ResortName = H.ResortName OR L.ResortName IS NULL)
GROUP BY TH.TourId
HAVING COUNT(H.CountryId) = COUNT(L.CountryId)
...