'Eksik verileri' yansıtmanız gerektiğinde birçok kullanım gördüm. Örneğin. Bir zaman seriniz var (örneğin bir erişim günlüğü) ve son 30 gün boyunca günde isabet sayısını göstermek istiyorsunuz (analitik kontrol panelini düşünün). Bunu yaparsanız select count(...) from ... group by day
, her gün için sayımı elde edersiniz, ancak sonuçta yalnızca en az bir erişiminiz olan her gün için bir satır bulunur. Öte yandan, ilk önce sayılar tablonuzdan ( select dateadd(day, -number, today) as day from numbers
) sonra bir gün tablosu yansıtırsanız ve sonra sayımlarla (veya dış başvurunuz, ne isterseniz) katılırsanız, o zaman sayınız için 0 olan bir sonuç alırsınız. erişimi yoktu. Bu sadece bir örnek. Tabii ki, gösterge tablonuzun sunum katmanının eksik günleri idare edebileceğini ve sadece 0 gösterebileceğini iddia edebilir, ancak bazı araçlar (örn. SSRS) bunu kaldıramaz.
Gördüğüm diğer örnekler, tüm pencere hesaplamalarını yapmak için benzer zaman serileri (tarih / saat +/- numarası) kullandı. Genel olarak, ne zaman zorunlu bir dilde iyi bilinen sayıda yinelemeye sahip bir for döngüsü kullanacaksanız, SQL'in bildirimsel ve ayarlanmış niteliği bir sayı tablosuna dayalı bir numara kullanabilir.
BTW, bir sayı tablosu kullanmakla birlikte , zorunlu işlem yürütme gibi hissettirse de , zorunlu olduğunu varsayma yanılsamasına düşmediği gerçeğini söylememe gerek olduğunu hissediyorum . Bir örnek vereyim:
int x;
for (int i=0;i<1000000;++i)
x = i;
printf("%d",x);
Bu program 999999'u yayınlayacaktır, ki bu neredeyse garantilidir.
Bir sayı tablosu kullanarak, SQL Server'da aynı deneyelim. İlk önce 1.000.000 kişilik bir tablo oluşturun:
create table numbers (number int not null primary key);
go
declare @i int = 0
, @j int = 0;
set nocount on;
begin transaction
while @i < 1000
begin
set @j = 0;
while @j < 1000
begin
insert into numbers (number)
values (@j*1000+@i);
set @j += 1;
end
commit;
raiserror (N'Inserted %d*1000', 0, 0, @i)
begin transaction;
set @i += 1;
end
commit
go
Şimdi 'for loop' yapalım:
declare @x int;
select @x = number
from numbers with(nolock);
select @x as [@x];
Sonuç:
@x
-----------
88698
(Sonuçta artık bir WTF anı yaşıyorsanız number
olan kümelenmiş birincil anahtar!), Hüner denir tahsisi düzeni taramak ve ben eklemek vermedi @j*1000+@i
kaza ... Ayrıca vardı bir tahmin girişim ve sonuç çünkü söyleyebiliriz paralellik ve bazen olabilir doğru cevap olsun.
Bu köprünün altında pek çok trol var ve bazı SQL Server boolean operatöründe kısa devre olduğundan bahsetmiştim ve T-SQL işlevleri belirli bir işlem sırası anlamına gelmiyor