web-dev-qa-db-fra.com

Mise à jour de la colonne int dans la table avec des valeurs d'incrémentation uniques

J'essaie de renseigner toutes les lignes manquant une valeur dans leur colonne InterfaceID (INT) avec une valeur unique par ligne.

J'essaie de faire cette requête:

UPDATE prices SET interfaceID = (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices) 
       WHERE interfaceID IS null

J'espérais le (SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices) serait évalué pour chaque ligne, mais ce n’est fait qu’une seule fois et toutes les lignes concernées obtiennent la même valeur au lieu de valeurs différentes.

Cela peut-il être fait en une seule requête?

49
Malcolm O'Hare
declare @i int  = SELECT ISNULL(MAX(interfaceID),0) + 1 FROM prices


update prices
set interfaceID  = @i , @i = @i + 1
where interfaceID is null

devrait faire le travail

75
WKordos
DECLARE @IncrementValue int
SET @IncrementValue = 0 
UPDATE Samples SET qty = @IncrementValue,@IncrementValue=@IncrementValue+1
17
ram nainar

requête simple serait, il suffit de définir une variable à un nombre que vous voulez. puis mettez à jour la colonne dont vous avez besoin en incrémentant de 1 à partir de ce nombre. pour toutes les lignes, il va mettre à jour chaque ID de ligne en incrémentant 1

SET @a  = 50000835 ;  
UPDATE `civicrm_contact` SET external_identifier = @a:=@a+1 
WHERE external_identifier IS NULL;
4
Developer

Dans les produits Oracle, vous pouvez utiliser l'instruction suivante:

update table set interfaceID=RowNum where condition;
2
HamedKhan

Pour Postgres

ALTER TABLE table_name ADD field_name serial PRIMARY KEY

REFERENCE: https://www.tutorialspoint.com/postgresql/postgresql_using_autoincrement.htm

2
Nikhil Bhardwaj

Essayez quelque chose comme ça:

with toupdate as (
    select p.*,
           (coalesce(max(interfaceid) over (), 0) +
            row_number() over (order by (select NULL))
           ) as newInterfaceId
    from prices
   )
update p
    set interfaceId = newInterfaceId
    where interfaceId is NULL

Cela ne les rend pas tout à fait consécutifs, mais attribue de nouveaux identifiants plus élevés. Pour les rendre consécutifs, essayez ceci:

with toupdate as (
    select p.*,
           (coalesce(max(interfaceid) over (), 0) +
            row_number() over (partition by interfaceId order by (select NULL))
           ) as newInterfaceId
    from prices
   )
update p
    set interfaceId = newInterfaceId
    where interfaceId is NULL
1
Gordon Linoff

En supposant que vous ayez une clé primaire pour cette table (vous devriez l'avoir), en plus d'utiliser un CTE ou un WITH, il est également possible d'utiliser une mise à jour avec une jointure automatique vers la même table:

UPDATE a
SET a.interfaceId = b.sequence
FROM prices a
INNER JOIN
(
   SELECT ROW_NUMBER() OVER ( ORDER BY b.priceId ) + ( SELECT MAX( interfaceId ) + 1 FROM prices ) AS sequence, b.priceId
   FROM prices b
   WHERE b.interfaceId IS NULL
) b ON b.priceId = a.priceId

J'ai supposé que la clé primaire est price-id.

La table dérivée, alias b, est utilisée pour générer la séquence via la fonction ROW_NUMBER () avec la ou les colonnes de clé primaire. Pour chaque ligne où la colonne interface-id est NULL, cela générera une ligne avec une valeur de séquence unique ainsi que la valeur de la clé primaire.

Il est possible d'ordonner la séquence dans un autre ordre plutôt que la clé primaire.

La séquence est compensée par l'ID d'interface MAX actuel + 1 via une sous-requête. La fonction MAX () ignore les valeurs NULL.

La clause WHERE limite la mise à jour aux lignes NULL.

La table dérivée est ensuite jointe à la même table, alias a, rejoignant la ou les colonnes de clé primaire avec la colonne à mettre à jour définie sur la séquence générée.

1
Kevin Swann