2016-04-12 25 views
1

ÖyleTarih aralığı nasıl değerlenir?

enter image description here

gibi bir tablo var Ve bu kod ile ben

Eh istiyorum ne ister her domainId

;WITH grp AS 
(
    SELECT DomainId, [Date],Passed, DatabasePerformance,ServerPerformance, 
    rn = ROW_NUMBER() OVER 
    (PARTITION BY DomainId ORDER BY [Date] DESC) 
    FROM dbo.DomainDetailDataHistory H 
) 
    SELECT g.DomainId, g.[Date],g.Passed, g.ServerPerformance, g.DatabasePerformance 
    FROM grp g 
    INNER JOIN @Latest T ON T.DomainId = g.DomainId 
    WHERE rn < 7 AND t.date != g.[Date] 
    ORDER BY DomainId, [Date] DESC 

için 5 son değerleri almak Bu son 5 satırın her biri için kaç tane bilet satıldığını bilmek için ama aşağıdaki koşulla:

Bu satırların her biri, farklı olan kendi tarihleriyle gelir. Her bir tarih için Son 15 dakika içinde kaç tane satıldığını ve kaç 30 milyonu sattığını kontrol etmek istiyorum.

Örnek:

Ben iki sütun, "soldTicketsLast15" ve "soldTicketsLast30"

tarih ile yukarıda uzatmak istediğiniz her domainId

enter image description here

için bu 5 satır olsun sütun ihtiyacım olan tarihlerin her birini içerir ve bu tarihlerin her biri için 15 dakika geri dönmek ve 30dk'a geri dönmek ve ne kadar bilet satıldığını öğrenmek

Örnek:

i gerçekleştirebilirsiniz Nasıl
SELECT MAX(SoldTickets) FROM DomainDetailDataHistory 
WHERE [Date] >= DATEADD(minute, -15, '2016-04-12 12:10:28.2270000') 

SELECT MAX(SoldTickets) FROM DomainDetailDataHistory 
WHERE [Date] >= DATEADD(minute, -30, '2016-04-12 12:10:28.2270000') 

?

+2

Neden operatör arasında kullanılmıyor? – Erick

+1

"Verilen bir domainId için bu 5 satırı alıyorum". Örnek sonuçlarınızın dahil ettiğiniz sorgu ile ne ilgisi olduğunu bilmiyorum. –

+0

@Erick Yalnızlık gösterebilir misiniz? Sql hakkındaki bilgimi oldukça yeşil görüyorum. – ThunD3eR

cevap

1

OUTER APPLY or CROSS APPLY'u kullanırdım.

;WITH grp AS 
(
    SELECT 
     DomainId, [Date], Passed, DatabasePerformance, ServerPerformance, 
     rn = ROW_NUMBER() OVER (PARTITION BY DomainId ORDER BY [Date] DESC) 
    FROM dbo.DomainDetailDataHistory H 
) 
SELECT 
    g.DomainId, g.[Date],g.Passed, g.ServerPerformance, g.DatabasePerformance 
    ,A15.SoldTicketsLast15 
    ,A30.SoldTicketsLast30 
FROM 
    grp g 
    INNER JOIN @Latest T ON T.DomainId = g.DomainId 
    OUTER APPLY 
    (
     SELECT MAX(H.SoldTickets) - MIN(H.SoldTickets) AS SoldTicketsLast15 
     FROM DomainDetailDataHistory AS H 
     WHERE 
      H.DomainId = g.DomainId AND 
      H.[Date] >= DATEADD(minute, -15, g.[Date]) 
    ) AS A15 
    OUTER APPLY 
    (
     SELECT MAX(H.SoldTickets) - MIN(H.SoldTickets) AS SoldTicketsLast30 
     FROM DomainDetailDataHistory AS H 
     WHERE 
      H.DomainId = g.DomainId AND 
      H.[Date] >= DATEADD(minute, -30, g.[Date]) 
    ) AS A30 
WHERE 
    rn < 7 
    AND T.[date] != g.[Date] 
ORDER BY DomainId, [Date] DESC; 

aşağıdaki gibi uygun bir indeks olmalıdır korelasyon APPLY sorgular verimli hale getirmek için: Bu endeks ayrıca sorgusu ( grp) verimli ana parçası yapmak için yardımcı olabilir

CREATE NONCLUSTERED INDEX [IX_DomainId_Date] ON [dbo].[DomainDetailDataHistory] 
(
    [DomainId] ASC, 
    [Date] ASC 
) 
INCLUDE ([SoldTickets]) 

.

+0

yapıldı. Düzenlemelerimden sonra bu işe yaradı ama bana büyük bir performans sorunu verdi. Sunulan çözüm, verilen her bir DomaInId için 15 & 30min biletler istedim ve bunun için min ve max değerlerini kontrol etmem gerekmedi. Bahsettiğim gibi bu büyük bir performans sorunu yaratıyor ve bunu optimize etmek için herhangi bir Fikriniz varsa merak ediyorum. – ThunD3eR

+0

Performans ayrı bir sorudur. Genellikle uygun bir dizine sahip olmanız gerekir. Bunun için 'OUTER APPLY' sorgusu uygun indekste (DomainID, Date) INCLUDE SoldTickets 'üzerinde görünecektir. Ayrıca, "MIN" ve "MAX" yerine, "ORDER BY" ile ilgili TOP (1) 'i kullanmak daha iyi olabilir. –

+0

Bu doğru bir soru soruyorsunuz. Ancak forumun bunun cevabını alabilecek bir şeyle spam olacağını düşünüyordum. Dizinle sololaşmayı düzenlemeyi düşünür müsünüz? – ThunD3eR

-1

Sorunuzu doğru bir şekilde anladıysam, 15 dakika ve 30 dakika öncesine dayanan tarihlerinizden (Tarih sütunundaki) satılan biletleri almak istersiniz. Eğer doğru DATEADD işlevini kullanarak varsayarsak, şu çalışmalıdır:

SELECT MAX(SoldTickets) FROM DomainDetailDataHistory 
WHERE [Date] BETWEEN [DATE] AND DATEADD(minute, -15, '2016-04-12 12:10:28.2270000') GROUP BY [SoldTickets] 

is operatörü iki tarih parametreler arasındaki sonuçlar almak için izin verir arasında. Yukarıdaki SQL'de, GROUPING işlevini (MAX) kullandığınızdan bir gruba da ihtiyacımız var. Grup, ne gruplamak istediğinize bağlı olacaktı ama ben sizin durumunuzda SoldTickets olacağını düşünüyorum.

Yukarıdaki SQL, tarih ile 15 dakika arasında olanları size verecektir. 30 dakika geriye benzer bir şey yapabilirsin.

+0

Ben ilk kod parçacığı iki sütun m8 ile genişletmek istiyorum. son seçim örneğin amaçlandı. Bu soru için yapılan güncellemeler – ThunD3eR

İlgili konular