従業員の不在の詳細に関するレコードを含むテーブルがあります。既存の行が更新される代わりに不在が更新されるとき、代わりに新しい行が作成され、前のレコードのLinkedRecordIdフィールドに新しいレコードのIDが設定されます.LinkedRecordIdフィールドのNULL値は、そのレコードがチェーン内で最新であることを示します。複数のリンクされたレコードの複数の文字列をレコードチェーンごとに1つの文字列に連結する効率的な方法
各親レコードのメモを1つの文字列に結合したすべての不在レコードのデータセットを取得し、チェーンの最新レコードの他のフィールドをリストする必要があります。私の問題は、パフォーマンスある
CREATE TABLE [dbo].[AbsenceData](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Notes] [varchar](max) NULL,
[LinkedRecordId] [int] NULL,
[CreatedAt] [datetime] NULL
)
;:ここ
は、データを含むテーブルのカットダウン版です現在の実装のカットダウン版ここで
CREATE FUNCTION [dbo].[AbsenceNotesFor](@AbsenceDataId INT)
RETURNS @return TABLE
(
AbsenceDataId INT
,Notes VARCHAR(MAX)
)
AS
BEGIN
DECLARE @notes VARCHAR(MAX)
;WITH AbsenceNotes AS (
SELECT
ad.Id
,ad.Notes
,ad.CreatedAt
FROM
AbsenceData ad WITH (NOLOCK)
WHERE
ad.Id = @absenceDataId
UNION ALL
SELECT
ad.Id
,ad.Notes
,ad.CreatedAt
FROM
AbsenceData ad WITH (NOLOCK)
INNER JOIN AbsenceNotes an ON an.Id = ad.LinkedRecordId
)
SELECT @notes = CONVERT(VARCHAR(11),CreatedAt, 105) + ' ' + CONVERT(VARCHAR(5),CreatedAt, 114)+ CHAR(13)+CHAR(10) + CAST(Notes AS VARCHAR(MAX)) + CHAR(13)+CHAR(10) + CHAR(13)+CHAR(10) + COALESCE(@notes,'')
FROM AbsenceNotes
INSERT INTO @return
SELECT AbsenceDataId = @AbsenceDataId, Notes = @notes
RETURN;
END
されています:
SELECT
Id
,n.Notes
FROM AbsenceData
CROSS APPLY dbo.AbsenceNotesFor(Id) n
WHERE
LinkedRecordId IS NULL
私の現在のソリューションを収集し、チェーン内のすべての親レコードから文字列を連結し、次のテーブル値関数を使用することです
これを数百レコードのデータセットに対して実行すると、テーブル値関数内のロジックに起因すると思われるパフォーマンスの問題が既に表示されます。
私はこれを行うより効率的な方法をお探しですか?
は、我々はここでMS SQL Serverの2016標準
を使用してSQLフィドルの一例であるされています。マルチステートメントの構文と http://sqlfiddle.com/#!6/b9834
テーブル価値関数 - 特にこのような複雑なものは、パフォーマンスを低下させるでしょう。あなたのやりたいことをする良い方法があるかもしれないので、あなたはあなたの質問を編集し、サンプルデータと望ましい結果を提供するべきです。 –