2017-06-30 1 views
0

Grundsätzlich Ich habe Product-Tabelle wie folgt aus:Wie kann eine Spalte basierend auf dem Wert einer anderen Spalte in SQL aktualisiert werden?

date  price 
--------- ----- 
02-SEP-14  50 
03-SEP-14  60 
04-SEP-14  60 
05-SEP-14  60 
07-SEP-14  71 
08-SEP-14  45 
09-SEP-14  45 
10-SEP-14  24 
11-SEP-14  60 

Ich brauche die Tabelle in dieser Form zu aktualisieren

date  price id 
--------- ----- -- 
02-SEP-14  50 1 
03-SEP-14  60 2 
04-SEP-14  60 2 
05-SEP-14  60 2 
07-SEP-14  71 3 
08-SEP-14  45 4 
09-SEP-14  45 4 
10-SEP-14  24 5 
11-SEP-14  60 6 

Was ich versucht habe:

CREATE SEQUENCE user_id_seq 
    START WITH 1 
    INCREMENT BY 1 
    CACHE 20; 

ALTER TABLE Product 
    ADD (ID number); 

UPDATE Product SET ID = user_id_seq.nextval; 

Dies ist die Aktualisierung der ID in der üblichen Weise wie e 1,2,3,4,5 ..

Ich habe keine Ahnung, wie es mit grundlegenden SQL-Befehlen zu tun. Bitte schlagen Sie vor, wie ich es machen kann. Vielen Dank im Voraus.

+0

Wo hat der erste Preis (50) kommen aus? Es ist im gewünschten Ergebnis, aber nicht in den Eingaben. Dann: Ordnen Sie eine neue Nummer zu, wenn der neue Preis von dem unmittelbar vorhergehenden abweicht? Oder nur, wenn es für die gesamte Sequenz neu ist? Sagen Sie also zum Beispiel, dass 11-SEP-14 den Preis 60 hat. Ordnen Sie die Nummer 6 zu, oder ordnen Sie die Nummer 2 zu? – mathguy

+0

Auch: Möchten Sie diese Daten wirklich SPEICHERN, oder ist es besser, eine Ansicht zu erstellen, in der die Spalte dynamisch berechnet wird? Wenn Sie diese in Ihrer Basistabelle speichern, was tun Sie, wenn Sie die Basisdaten ändern müssen (z. B. eine Korrektur des Preises 04-SEP-14, Aktualisierung von 60 auf 55)? – mathguy

+0

Ich habe gerade die Frage bearbeitet. Ich hoffe jetzt ist es besser zu verstehen. –

Antwort

1

hier zu tun, ist eine Möglichkeit, eine Ansicht von Ihren Basisdaten zu erstellen. Ich nehme an, Sie haben mehr als ein Produkt (identifiziert durch Produkt-ID), und dass die Preisdaten nicht unbedingt aufeinander folgen. Die Reihenfolge ist für jede Produkt-ID separat. (Auch product sollte der Name einer anderen Tabelle sein - wobei die Produkt-ID der Primärschlüssel ist und Sie andere Informationen wie Produktname, Kategorie usw. haben. Die Tabelle in Ihrem Beitrag würde eher wie price_history heißen.)

alter session set nls_date_format='dd-MON-rr'; 

create table product (prod_id number, dt date, price number); 

insert into product (prod_id, dt, price) 
    select 101, '02-SEP-14', 50 from dual union all 
    select 101, '03-SEP-14', 60 from dual union all 
    select 101, '04-SEP-14', 60 from dual union all 
    select 101, '05-SEP-14', 60 from dual union all 
    select 101, '07-SEP-14', 71 from dual union all 
    select 101, '08-SEP-14', 45 from dual union all 
    select 101, '09-SEP-14', 45 from dual union all 
    select 101, '10-SEP-14', 24 from dual union all 
    select 101, '11-SEP-14', 60 from dual union all 
    select 102, '02-SEP-14', 45 from dual union all 
    select 102, '04-SEP-14', 45 from dual union all 
    select 102, '05-SEP-14', 60 from dual union all 
    select 102, '06-SEP-14', 50 from dual union all 
    select 102, '09-SEP-14', 60 from dual 
; 

commit; 

create view product_vw (prod_id, dt, price, seq) as 
    select prod_id, dt, price, 
     count(flag) over (partition by prod_id order by dt) 
    from (select prod_id, dt, price, 
        case when price = lag(price) over (partition by prod_id order by dt) 
         then null else 1 end as flag 
      from product 
     ) 
; 

überprüfen Sie nun, was die Ansicht wie folgt aussieht:

select * from product_vw; 

PROD_ID DT      PRICE  SEQ 
------- ------------------- ---------- ---------- 
    101 02/09/0014 00:00:00   50   1 
    101 03/09/0014 00:00:00   60   2 
    101 04/09/0014 00:00:00   60   2 
    101 05/09/0014 00:00:00   60   2 
    101 07/09/0014 00:00:00   71   3 
    101 08/09/0014 00:00:00   45   4 
    101 09/09/0014 00:00:00   45   4 
    101 10/09/0014 00:00:00   24   5 
    101 11/09/0014 00:00:00   60   6 
    102 02/09/0014 00:00:00   45   1 
    102 04/09/0014 00:00:00   45   1 
    102 05/09/0014 00:00:00   60   2 
    102 06/09/0014 00:00:00   50   3 
    102 09/09/0014 00:00:00   60   4 
+0

Ist es möglich ohne PROD_ID? Es wird nicht möglich sein, zusätzliche Spalten in der Tabelle hinzuzufügen. Wenn ich Ansicht verwende, erwarte ich, dass mein Tisch nicht geändert wird. –

+0

@SOUBHIKRAKSHIT - meinst du, du hast nur ein Produkt? Dann entferne 'partition by prod_id' überall und entferne alle anderen Vorkommen von' prod_id'; Es sollten keine weiteren Änderungen erforderlich sein. – mathguy

+0

Vielen Dank. Es funktioniert gut. –

0

HINWEIS: Dies beantwortet die Frage, die ursprünglich gestellt wurde. Das OP hat die Daten geändert.

Wenn Ihre Daten nicht zu groß ist, können Sie eine korrelierte Unterabfrage verwenden:

update product p 
    set id = (select count(distinct p2.price) 
       from product p2 
       where p2.date <= p.date 
      ); 

Wenn Ihre Daten größer ist, dann merge ist besser geeignet.

+0

Dies führt nicht zum vom OP gewünschten Ergebnis.Derselbe Preis wird nur für aufeinanderfolgende Daten mit der gleichen fortlaufenden Nummer versehen. es wird eine andere Seq-Nummer erhalten, wenn es dazwischenliegende Tage mit unterschiedlichen Preisen gibt. Der ursprüngliche Beitrag war nicht klar darüber; darum geht es bei Folgefragen. – mathguy

+0

Ja .. Diese Abfrage wird nicht die gewünschte Ausgabe erzeugen. Würden Sie bitte die Lösung geben, wenn die Daten größer sind? –

+0

@mathguy. . . Das OP hat die Daten geändert. Dies beantwortet die ursprüngliche Frage (Sie können sich den Bearbeitungsverlauf ansehen). Ich habe dazu eine Notiz hinzugefügt. –

-2

Dies ist der beste Weg, um zu versuchen. Es gibt keine andere einfache Möglichkeit, dies mit einfachen Aussagen

0
WITH cts AS 
(
SELECT row_number() over (partition by price order by price) as id 
,date 
,price 
FROM Product 
) 
UPDATE p 
set p.id = cts.id 
from product p join cts on cts.id = p.id 
+0

Dies ist ungültig für Oracle –

Verwandte Themen