Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Đếm các tham chiếu đến một bản ghi trong bảng thông qua Phím ngoại

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ả.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hướng dẫn Xây dựng và Triển khai Máy chủ Cơ sở dữ liệu Chung

  2. Điều gì tốt hơn cho ứng dụng dữ liệu lớn của bạn, SQL hoặc NoSQL?

  3. Giới hạn con trỏ truy vấn API Salesforce

  4. Hiểu biết về làm lại nhóm nhật ký so với tệp và thành viên

  5. Loại bỏ sự trùng lặp của biểu thức vị trí trong ứng dụng