Saya telah menulis permintaan SQL Server yang memperbarui catatan untuk memiliki nomor urut setelah mempartisi di lapangan. Ketika saya menjalankannya sebagai pernyataan SELECT, semuanya tampak hebat:
DECLARE @RunDetailID INT = 448
DECLARE @JobDetailID INT
SELECT @JobDetailID = [JobDetailID] FROM [RunDetails] WHERE [RunDetailID] = @RunDetailID
SELECT
[OrderedRecords].[NewSeq9],
RIGHT([OrderedRecords].[NewSeq9], 4)
FROM
(
SELECT
[Records].*,
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
FROM
(
SELECT
[MRDFStorageID],
[RunDetailID],
[SortField],
[PieceID],
[Seq9],
[BallotType]
FROM
[MRDFStorage]
JOIN [BallotStyles] ON [MRDFStorage].[SortField] = [BallotStyles].[Style] and [BallotStyles].[JobDetailID] = @JobDetailID
WHERE
[RunDetailID] IN (SELECT [RunDetailID] FROM [RunDetails] WHERE [JobDetailID] = @JobDetailID AND [RunStatusID] <> 0)
) Records
) OrderedRecords
JOIN MRDFStorage ON [OrderedRecords].[MRDFStorageID] = [MRDFStorage].[MRDFStorageID]
WHERE
[MRDFStorage].[RunDetailID] = @RunDetailID
Namun, ketika saya membuat kueri menjadi perintah UPDATE, itu mulai melewatkan angka genap:
DECLARE @RunDetailID INT = 448
DECLARE @JobDetailID INT
SELECT @JobDetailID = [JobDetailID] FROM [RunDetails] WHERE [RunDetailID] = @RunDetailID
UPDATE
[MRDFStorage]
SET
[Seq9] = [OrderedRecords].[NewSeq9],
[Overlay1] = [OrderedRecords].[NewSeq9],
[Overlay10] = RIGHT([OrderedRecords].[NewSeq9], 4)
FROM
(
SELECT
[Records].*,
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
FROM
(
SELECT
[MRDFStorageID],
[RunDetailID],
[SortField],
[PieceID],
[Seq9],
[BallotType],
CAST([SpecialProcessing] as Int) StartCount
FROM
[MRDFStorage]
JOIN [BallotStyles] ON [MRDFStorage].[SortField] = [BallotStyles].[Style] and [BallotStyles].[JobDetailID] = @JobDetailID
WHERE
[RunDetailID] IN (SELECT [RunDetailID] FROM [RunDetails] WHERE [JobDetailID] = @JobDetailID AND [RunStatusID] <> 0)
) Records
) OrderedRecords
JOIN MRDFStorage ON [OrderedRecords].[MRDFStorageID] = [MRDFStorage].[MRDFStorageID]
WHERE
[MRDFStorage].[RunDetailID] = @RunDetailID
Saya sudah mencoba secara khusus berfokus pada bagian ini:
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
Apakah ada efek samping yang saya tidak ketahui?
DIPERBARUI DENGAN DEFINISI TABEL
CREATE TABLE [dbo].[MRDFStorage] (
[MRDFStorageID] INT IDENTITY (1, 1) NOT NULL,
[RunDetailID] INT NOT NULL,
[PieceID] VARCHAR (15) NULL,
[SortField] VARCHAR (20) NULL,
[BallotType] VARCHAR (100) NULL,
[Seq9] VARCHAR (15) NULL,
CONSTRAINT [PK_MRDFStorage] PRIMARY KEY CLUSTERED ([MRDFStorageID] ASC),
CONSTRAINT [FK_MRDFStorage_RunDetails] FOREIGN KEY ([RunDetailID]) REFERENCES [dbo].[RunDetails] ([RunDetailID])
);
CREATE TABLE [dbo].[BallotStyles] (
[BallotStyleID] INT IDENTITY (1, 1) NOT NULL,
[JobDetailID] INT NOT NULL,
[Style] VARCHAR (20) NOT NULL,
CONSTRAINT [PK_BallotStyles] PRIMARY KEY CLUSTERED ([BallotStyleID] ASC)
);
CREATE TABLE [dbo].[RunDetails] (
[RunDetailID] INT IDENTITY (1, 1) NOT NULL,
[JobDetailID] INT NOT NULL,
CONSTRAINT [PK_RunDetails] PRIMARY KEY CLUSTERED ([RunDetailID] ASC)
);
sql-server
update
subquery
window-functions
Chris Schiffhauer
sumber
sumber
UPDATE [MRDFStorage]
denganUPDATE m
danJOIN MRDFStorage ON ...
dengan.JOIN MRDFStorage m ON ...
Saya khawatir UPDATE mungkin memperbarui beberapa baris lebih dari sekali. Baca postingan blog ini: Mari kita hapuskan UPDATE DARI!Jawaban:
Tidak melihat data yang Anda miliki membuat ini sedikit lebih sulit tetapi saya berhasil mereproduksi apa yang Anda lihat jika Anda melihatnya dengan ini:
Faktor kunci di sini adalah dua baris di
BallotStyles
.Anda bergabung ke
BallotStyles
dalam kueri paling dalam dan dengan data seperti di atas Anda akan mendapatkan baris duplikat untuk setiap baris diMRDFStorage
. Karena Anda tidak menggunakan salah satu kolom di dalamBallotStyles
Anda hanya memeriksa keberadaan baris dan itu dapat dilakukan denganexists
klausa sebagai gantinya dan itu tentu saja tidak akan membuat baris duplikat.sumber