PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

बिना किसी संख्या के गुम हुए, मैं लगातार, बढ़ती हुई संख्याओं वाला कॉलम कैसे प्राप्त करूं?

इसे पिछले उत्तर से अनुकूलित किया। इस तरह की चीजें अक्सर तब होती हैं जब एप्लिकेशन टैबिंग-ऑर्डर . चाहते हैं चर के लिए (पढ़ें:एक ईएवी मॉडल में रिकॉर्ड), जो एक वैकल्पिक कुंजी (का हिस्सा) भी हो सकता है।

  • priority क्षेत्र को लगातार रखने की जरूरत है। [यह टैबिंग-आदेश है ]
  • INSERT पर:प्राथमिकता वाले सभी रिकॉर्ड>=नए रिकॉर्ड की प्राथमिकताएं बढ़ाई जानी चाहिए
  • इसी तरह:DELETE पर -> घटा हुआ
  • यदि किसी रिकॉर्ड की प्राथमिकता को अद्यतन द्वारा बदल दिया जाता है, तो पुराने और नए प्राथमिकता मान के बीच के रिकॉर्ड की प्राथमिकताएं ऊपर या नीचे स्थानांतरित होनी चाहिए।
  • पुनरावर्ती ट्रिगर आमंत्रण से बचने के लिए:
    • ट्रिगर-आधारित अपडेट flipflag को फ़्लिप करते हैं वे जिस भी रिकॉर्ड को छूते हैं।
    • और वे old.flipflag=new.flipflag . के लिए परीक्षण करते हैं असली का पता लगाने के लिए अद्यतन। (जो ट्रिगर के कारण नहीं होते हैं)
        -- Make some data
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE fruits
        ( id INTEGER NOT NULL PRIMARY KEY
        , priority INTEGER NOT NULL
        , flipflag boolean NOT NULL default false
        , zname varchar NOT NULL
        , CONSTRAINT unique_priority UNIQUE (priority) DEFERRABLE INITIALLY DEFERRED
        );
INSERT INTO fruits(id,zname,priority) VALUES
 (1  , 'Pear' ,4)
,(2  , 'Apple' ,2)
,(3  , 'Orange' ,1)
,(4  , 'Banana' ,3)
,(5  , 'Peach' ,5)
        ;

        -- Trigger functions for Insert/update/delete
CREATE function shift_priority()
RETURNS TRIGGER AS $body$

BEGIN
        UPDATE fruits fr
        SET priority = priority +1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE NEW.priority < OLD.priority
        AND OLD.flipflag = NEW.flipflag -- redundant condition
        AND fr.priority >= NEW.priority
        AND fr.priority < OLD.priority
        AND fr.id <> NEW.id             -- exlude the initiating row
                ;
        UPDATE fruits fr
        SET priority = priority -1
        , flipflag = NOT flipflag
        WHERE NEW.priority > OLD.priority
        AND OLD.flipflag = NEW.flipflag
        AND fr.priority <= NEW.priority
        AND fr.priority > OLD.priority
        AND fr.id <> NEW.id
        ;
        RETURN NEW;
END;

$body$
language plpgsql;

CREATE function shift_down_priority()
RETURNS TRIGGER AS $body$

BEGIN

        UPDATE fruits fr
        SET priority = priority -1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE fr.priority > OLD.priority
                ;
        RETURN NEW;
END;

$body$
language plpgsql;

CREATE function shift_up_priority()
RETURNS TRIGGER AS $body$

BEGIN
        UPDATE fruits fr
        SET priority = priority +1
        , flipflag = NOT flipflag       -- alternating bit protocol ;-)
        WHERE fr.priority >= NEW.priority
                ;
        RETURN NEW;
END;

$body$
language plpgsql;

        -- Triggers for Insert/Update/Delete
CREATE TRIGGER shift_priority_u
        AFTER UPDATE OF priority ON fruits
        FOR EACH ROW
        WHEN (OLD.flipflag = NEW.flipflag AND OLD.priority <> NEW.priority)
        EXECUTE PROCEDURE shift_priority()
        ;
CREATE TRIGGER shift_priority_d
        AFTER DELETE ON fruits
        FOR EACH ROW
        EXECUTE PROCEDURE shift_down_priority()
        ;
CREATE TRIGGER shift_priority_i
        BEFORE INSERT ON fruits
        FOR EACH ROW
        EXECUTE PROCEDURE shift_up_priority()
        ;

        -- Do some I/U/D operations
\echo Pears are Okay
UPDATE fruits
SET priority = 1
WHERE id=1; -- 1,4

SELECT * FROM fruits ORDER BY priority;

\echo dont want bananas
DELETE FROM fruits WHERE id = 4;
SELECT * FROM fruits ORDER BY priority;

\echo  We want Kiwis
INSERT INTO fruits(id,zname,priority) VALUES (4  , 'Kiwi' ,3) ;
SELECT * FROM fruits ORDER BY priority;

परिणाम:

Pears are Okay
UPDATE 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  2 |        3 | t        | Apple
  4 |        4 | t        | Banana
  5 |        5 | f        | Peach
(5 rows)

dont want bananas
DELETE 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  2 |        3 | t        | Apple
  5 |        4 | t        | Peach
(4 rows)

We want Kiwis
INSERT 0 1
 id | priority | flipflag | zname  
----+----------+----------+--------
  1 |        1 | f        | Pear
  3 |        2 | t        | Orange
  4 |        3 | f        | Kiwi
  2 |        4 | f        | Apple
  5 |        5 | f        | Peach
(5 rows)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. दो सरणियों की तुलना कैसे करें और केवल गैर मेल खाने वाले तत्वों को चुनें पोस्टग्रेज में

  2. hasMany ने कुछ ऐसा कहा है जो Sequelize.Model . का उदाहरण नहीं है

  3. PostgreSQL उपयोगकर्ता समूह NL

  4. हमेशा अप-टू-डेट पढ़ने/लिखने के परीक्षण सर्वर को बनाए रखने के लिए PostgreSQL तार्किक प्रतिकृति का उपयोग करना

  5. क्या मुझे INDEX और UNIQUE INDEX दोनों को निर्दिष्ट करना चाहिए?