He escrito una consulta de SQL Server que actualiza los registros para que tengan un número secuencial después de la partición en un campo. Cuando lo ejecuto como una instrucción SELECT, todo se ve muy bien:
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
Sin embargo, cuando hago la consulta en un comando ACTUALIZAR, comienza a omitir números pares:
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
He intentado centrarme específicamente en esta porción:
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
¿Hay algún efecto secundario que ignore?
ACTUALIZAR CON DEFINICIONES DE TABLA
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
fuente
fuente
UPDATE [MRDFStorage]
conUPDATE m
y elJOIN MRDFStorage ON ...
con.JOIN MRDFStorage m ON ...
Me temo que la ACTUALIZACIÓN puede actualizar algunas filas más de una vez. Lea esta publicación de blog: ¡Vamos a desaprobar ACTUALIZAR DE!Respuestas:
No ver los datos que tienes hace que esto sea un poco más difícil, pero logré reproducir lo que ves si ves con esto:
El factor clave aquí son las dos filas
BallotStyles
.Se está uniendo a
BallotStyles
la consulta más interna y con datos como el anterior obtendrá filas duplicadas para cada filaMRDFStorage
. Dado que no está utilizando ninguna de las columnasBallotStyles
, solo está verificando la existencia de filas y eso se puede hacer con unaexists
cláusula y, por supuesto, eso no creará las filas duplicadas.fuente