Reputation: 2738
I need help please with writing a sproc, it takes a table-valued parameter @Locations, whose Type is defined as follows:
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)
)
@Locations will contain at least 1 row. Each row WILL have a non-null CountryId, and MAY have a non-null ResortName. Each row will have a unique Ordinal, the first being 0. The combinations of CountryId and ResortName in @Locations will be unique.
The sproc needs to search against the following table structure.
The image can be seen better by right-clicking it and View Image, or similar depending on your browser.
Now this is where I'm stuck, the sproc should be able to find Tours where:
Edit This is the code I finally used, based on Anthony Faull's suggestion. Thank you so much Anthony:
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
Upvotes: 2
Views: 426
Reputation: 17957
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
Upvotes: 1
Reputation: 17957
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)
Upvotes: 0