sql >> データベース >  >> RDS >> Database

外部キーを介したテーブル内のレコードへの参照のカウント

    最近、自分の目的でタスクを解決する必要がありました。テーブル(ファイル)の各レコードの外部キーによってリンクされた外部レコードの数を計算することです。このタスクはファイルテーブルの特定の構造で解決されましたが、必要に応じて、ソリューションをユニバーサルなものに作り直すことができます。

    このソリューションは、何百万ものレコードと毎分更新されることなく、アンロードされたデータベース用に開発されたため、パフォーマンスについてあまり心配していなかったことを明確にします。

    >

    主な理由は、ファイルテーブルへの外部リンクの数が開発中に変更される可能性があり、クエリを絶えず書き直すのは単に不合理であるためです。システムには特定のモジュール性が計画されていたため、すべての最終的なテーブルが正確にわかっているわけではありません。

    2つのラベルを作成するためのスクリプト:

    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)

    FileテーブルとTestForFilesテーブルを取得します。 TestForFilesテーブルは、IdFileForTestフィールドによってFileテーブルを参照します。

    次のデータセットを取得します。

    スクリプトは、テーブル内のレコード数をカウントするクエリを生成します。

    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;

    次のクエリが生成されます:

    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

    実行後、次のようなテーブルの内容があります。

    もう一度、タスクは特定のファイルテーブルに対して解決され、カウントはIdFileフィールドに外部キーがある場合にのみ機能します。

    この記事はによって翻訳されました 著者の許可を得たCodingsightチーム。


    1. Firebaseの概要

    2. 10進数のNLS_NUMERIC_CHARACTERS設定

    3. オブジェクト'DF__*'は列'*'に依存しています-intをdoubleに変更します

    4. SQLiteデータベースから画像を取得するにはどうすればよいですか?