Burada gerçek bir akıl karıştırıcı var!Çapraz tablo değerli bir işlev uygular
LeagueID Stake League_EntryID UserID TotalPoints TotalBonusPoints Prize
13028 2.00 58659 2812 15 5 NULL
13028 2.00 58662 3043 8 3 NULL
13029 5.00 58665 2812 8 3 NULL
League_EntryID burada eşsiz bir alandır ancak bu sorgu kullanıcı o gün için girildiğinden birden ligleri döndürür göreceksiniz:
Ben temelde bir lig kullanıcıları konumlandırır bir tablo var.
Ayrıca, lig için geçerli ödül puanlarını döndüren bir tablo değeri işlevim var ve bu, bir parametre olarak LeagueID'yi kabul eder ve ödül parası almaya hak kazanan kişileri döndürür. Bu, ideal olarak LeagueID'yi kabul eden işlev olarak tutmak istediğim karmaşık bir işlevdir. Bunun sonucu olarak aşağıdaki gibidir:
UserID Position League_EntryID WinPerc Prize
2812 1 58659 36.000000 14.00
3043 6 58662 2.933333 4.40
3075 6 58664 2.933333 4.40
Esasen ne yapmak istediğim esasen o League_EntryID yani
için Ödül alan güncelleştirmeye LigID ileterek üstteki sorguya tablo değeri işlevini katılmaktırSELECT * FROM [League]
INNER JOIN [League_Entry] ON [League].[LeagueID] = [League_Entry].[LeagueID]
INNER JOIN [dbo].[GetPrizesForLeague]([League].[LeagueID]) ....
CROSS APPLY'nin işe yarayıp yaramayacağından emin değilim ama aslında LeagueID ve League_EntryID'de JOIN'e ödülüm için bana değer vermem gerektiğine inanıyorum. Bunu skaler bir işlevi ziyaret etmeden yapmanın en iyi yolundan emin olamayacaksınız; bu da sırayla tablo değeri işlevini çağırır ve bundan Ödül kazanır.
Hız beni burada endişelendiriyor.
P.S. Tüm Lig_EntryID'leri tablo değeri fonksiyonunun bir parçası olarak mevcut olmayabilir, bu yüzden bir DIŞ JOIN/APPLY kullanılabilir mi?
DÜZENLEME
SELECT DISTINCT [LeagueID],
[CourseName],
[Refunded],
[EntryID],
[Stake],
d.[League_EntryID],
d.[UserID],
[TotalPoints],
[TotalBonusPoints],
[TotalPointsLastRace],
[TotalBonusPointsLastRace],
d.[Prize],
[LeagueSizeID],
[TotalPool],
d.[Position],
[PositionLastRace],
t.Prize
FROM
(
SELECT [LeagueID],
[EntryID],
[Stake],
[MeetingID],
[Refunded],
[UserID],
[League_EntryID],
[TotalPoints],
[TotalBonusPoints],
[TotalPointsLastRace],
[TotalBonusPointsLastRace],
[Prize],
[LeagueSizeID],
[dbo].[GetTotalPool]([LeagueID], 1) AS [TotalPool],
RANK() OVER(PARTITION BY [LeagueID] ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC) AS [Position],
RANK() OVER(PARTITION BY [LeagueID] ORDER BY [TotalPointsLastRace] DESC, [TotalBonusPointsLastRace] DESC) AS [PositionLastRace],
ROW_NUMBER() OVER (PARTITION BY [LeagueID]
ORDER BY [TotalPoints] DESC, [TotalBonusPoints] DESC
) as [Position_Rownum]
FROM [DATA]) AS d
INNER JOIN [Meeting] WITH (NOLOCK) ON [d].[MeetingID] = [Meeting].[MeetingID]
INNER JOIN [Course] ON [Meeting].[CourseID] = [Course].[CourseID]
OUTER APPLY (SELECT * FROM [dbo].[GetLeaguePrizes](d.[LeagueID])) t
WHERE (
([LeagueSizeID] = 3 AND [Position_Rownum] <= 50)
OR (d.[UserID] = @UserID AND [LeagueSizeID] = 3)
)
OR
(
[LeagueSizeID] in (1,2)
)
ORDER BY [LeagueID], [Position]
herhangi bir yönü, aşağıdaki sorgu takdir bakınız.
Performansı iyileştirmede yardıma ihtiyacınız varsa, tüm ayrıntıları içeren bir soru yayınlamanız gerekir: tablo ve dizin yapısı, sahip olduğunuz geçerli kod ve örnek veriler + beklenen sonuçlar, tercihen SQL Fiddle. Eğer işlev örneğin bir satır içi işleve dönüştürülebiliyorsa, performans çok daha iyi olmalı, ama tabiki bu durumda çok fazla bir şey var. –