Baru-baru ini saya perlu menyelesaikan tugas untuk tujuan saya sendiri:menghitung jumlah catatan eksternal yang ditautkan oleh kunci asing untuk setiap catatan dalam tabel (File). Tugas diselesaikan untuk struktur spesifik dari tabel File, tetapi jika perlu, solusinya dapat dikerjakan ulang menjadi yang universal.
Saya akan mengklarifikasi bahwa solusi tersebut dikembangkan untuk database yang tidak dimuat, tanpa jutaan catatan dan pembaruan setiap menit, jadi tidak ada banyak kekhawatiran tentang kinerjanya.
Alasan utamanya adalah jumlah tautan eksternal ke tabel File dapat berubah selama pengembangan dan tidak masuk akal untuk terus-menerus menulis ulang kueri. Modularitas tertentu direncanakan dalam sistem, oleh karena itu, semua tabel akhir tidak diketahui secara pasti.
Skrip untuk membuat dua label:
CREATE TABLE [dbo].[File]( [IdFile] [int] IDENTITY(1, 1) NOT NULL, [NameFile] [nvarchar](max) NOT NULL, [CountUsage] [int] NOT NULL, PRIMARY KEY (IdFile) ) SET identity_insert [dbo].[File] ON; INSERT INTO [dbo].[File] ([IdFile], [NameFile],[CountUsage]) VALUES (1, 'test1', 0), (2, 'test2', 1000) SET identity_insert [dbo].[File] OFF; CREATE TABLE [dbo].[TestForFiles]( [IdTest] [int] IDENTITY(1, 1) NOT NULL, [IdFileForTest] [int] NOT NULL, PRIMARY KEY (IdTest) ) ALTER TABLE [dbo].[TestForFiles] WITH CHECK ADD CONSTRAINT [FK_TestForFiles_File] FOREIGN KEY([IdFileForTest]) REFERENCES [dbo].[File] ([IdFile]) ALTER TABLE [dbo].[TestForFiles] CHECK CONSTRAINT [FK_TestForFiles_File] INSERT INTO [dbo].[TestForFiles] ([IdFileForTest]) VALUES (1), (1), (1), (2)
Kami mendapatkan tabel File dan TestForFiles. Tabel TestForFiles merujuk ke tabel File dengan bidang IdFileForTest.
Kami memperoleh kumpulan data berikut:
Skrip membuat kueri untuk menghitung jumlah record dalam tabel:
DECLARE @sql_tables nvarchar(max) = null; SELECT @sql_tables = CASE WHEN @sql_tables IS NULL THEN '' ELSE @sql_tables + CHAR(13) + CHAR(10) + ' UNION ALL' + CHAR(13) + CHAR(10) END + ' SELECT ' + c.name + ' AS IdFile, count(*) AS FileCount FROM ' + t.name + ' GROUP BY ' + c.name FROM sys.foreign_key_columns AS fk INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id AND fk.parent_column_id = c.column_id INNER JOIN sys.columns AS c2 ON fk.referenced_object_id = c2.object_id AND fk.referenced_column_id = c2.column_id WHERE fk.referenced_object_id = (SELECT object_id FROM sys.tables WHERE name = 'File') AND c2.name = 'IdFile'; IF @sql_tables IS NOT NULL BEGIN DECLARE @sql nvarchar(max) = 'UPDATE dbo.[File]' + CHAR(13) + CHAR(10) + 'SET CountUsage = t2.FileCount' + CHAR(13) + CHAR(10) + 'FROM dbo.[File]' + CHAR(13) + CHAR(10) + 'INNER JOIN (' + CHAR(13) + CHAR(10) + ' SELECT IdFile, SUM(FileCount) AS FileCount ' + CHAR(13) + CHAR(10) + ' FROM (' + CHAR(13) + CHAR(10) + @sql_tables + CHAR(13) + CHAR(10) + ' ) t' + CHAR(13) + CHAR(10) + ' GROUP BY IdFile' + CHAR(13) + CHAR(10) + ') t2 ON t2.IdFile = dbo.[File].IdFile'; print @sql; EXEC sp_executesql @sql; END;
Kueri berikut dibuat:
UPDATE dbo.[File] SET CountUsage = t2.FileCount FROM dbo.[File] INNER JOIN ( SELECT IdFile, SUM(FileCount) AS FileCount FROM ( SELECT IdFileForTest AS IdFile, count(*) AS FileCount FROM TestForFiles GROUP BY IdFileForTest ) t GROUP BY IdFile ) t2 ON t2.IdFile = dbo.[File].IdFile
Setelah eksekusi, kami memiliki isi tabel seperti ini:
Sekali lagi, tugas diselesaikan untuk tabel File tertentu, penghitungan hanya berfungsi untuk kasus ketika ada kunci asing di bidang IdFile.
Artikel ini diterjemahkan oleh Codingsight tim dengan izin dari penulis.