Gần đây, tôi cần giải quyết công việc cho mục đích riêng của mình:tính số lượng bản ghi bên ngoài được liên kết bằng khóa ngoại cho mỗi bản ghi trong bảng (Tệp). Nhiệm vụ đã được giải quyết cho cấu trúc cụ thể của bảng Tệp, nhưng nếu cần, giải pháp có thể được làm lại thành một giải pháp chung.
Tôi sẽ nói rõ rằng giải pháp được phát triển cho cơ sở dữ liệu chưa tải, không có hàng triệu bản ghi và cập nhật mỗi phút, vì vậy không có nhiều lo lắng về hiệu suất.
Nguyên nhân chính là do số lượng liên kết bên ngoài tới bảng Tệp có thể thay đổi trong quá trình phát triển và việc liên tục viết lại truy vấn sẽ là không hợp lý. Một mô-đun nhất định đã được lên kế hoạch trong hệ thống, do đó, tất cả các bảng cuối cùng không được biết chính xác.
Tập lệnh để tạo hai nhãn:
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)
Chúng tôi nhận được bảng File và TestForFiles. Bảng TestForFiles tham chiếu đến bảng Tệp theo trường IdFileForTest.
Chúng tôi thu được tập dữ liệu sau:
Tập lệnh tạo truy vấn để đếm số bản ghi trong bảng:
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;
Truy vấn sau được tạo:
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
Sau khi thực hiện, chúng ta có nội dung bảng như sau:
Một lần nữa, nhiệm vụ đã được giải quyết cho một bảng Tệp cụ thể, việc đếm chỉ hoạt động đối với các trường hợp có khóa ngoại trên trường IdFile.
Bài viết này được dịch bởi Nhóm Codingsight được sự cho phép của tác giả.