উপস্থাপনে বিরোধী সারির আইডি কীভাবে পাবেন?


18

আমার কাছে tagদুটি কলাম সহ একটি টেবিল রয়েছে: id(ইউইইডি) এবং name(পাঠ্য)। আমি এখন টেবিলটিতে একটি নতুন ট্যাগ সন্নিবেশ করতে চাই, তবে ট্যাগটি ইতিমধ্যে উপস্থিত থাকলে, আমি কেবল idবিদ্যমান রেকর্ডটি পেতে চাই ।

আমি ধরে নিয়েছিলাম যে আমি কেবল এর ON CONFLICT DO NOTHINGসাথে সংমিশ্রণে ব্যবহার করতে পারি RETURNING "id":

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT DO NOTHING
RETURNING "id";

"Foo" নামের ট্যাগটি যদি ইতিমধ্যে বিদ্যমান থাকে তবে এটি একটি খালি ফলাফল সেটটি দেয়।

আমি তখন নোপ ক্লজটি ব্যবহার করতে ক্যোয়ারীটি পরিবর্তন করেছি DO UPDATE:

INSERT INTO
    "tag" ("name")
VALUES( 'foo' )
ON CONFLICT ("name") DO UPDATE SET "name" = 'foo'
RETURNING "id";

এটি ইচ্ছাকৃত হিসাবে কাজ করে তবে এটি কিছুটা বিভ্রান্তিকর কারণ আমি ইতিমধ্যে বিদ্যমান মানটিতে নামটি সেট করছি।

এই সমস্যাটি সম্পর্কে কি এই উপায় বা আমি অনুপস্থিত একটি সহজ পদ্ধতির আছে?


তুমি কি চেষ্টা করেছ returning excluded.id?
a_horse_with_no_name

@a_horse_with_no_name যা ERROR: missing FROM-clause entry for table "excluded"ব্যবহারের সময় আমাকে দেয় DO NOTHING
ডের হচস্টাপলার

1
আরও দেখুন stackoverflow.com/a/42217872/1411457
harmic

উত্তর:


8

এটি 3 টি ক্ষেত্রে (যতদূর আমি পরীক্ষা করেছি) কাজ করবে, যদি সারণিতে সন্নিবেশ করা মানগুলি সমস্ত নতুন বা ইতিমধ্যে সমস্ত টেবিল বা একটি মিশ্রণে থাকে:

WITH
  val (name) AS
    ( VALUES                          -- rows to be inserted
        ('foo'),
        ('bar'),
        ('zzz')
    ),
  ins AS
    ( INSERT INTO
        tag (name)
      SELECT name FROM val
      ON CONFLICT (name) DO NOTHING
      RETURNING id, name              -- only the inserted ones
    )
SELECT COALESCE(ins.id, tag.id) AS id, 
       val.name
FROM val
  LEFT JOIN ins ON ins.name = val.name
  LEFT JOIN tag ON tag.name = val.name ;

এটি করার সম্ভবত আরও কিছু উপায় রয়েছে, সম্ভবত নতুন ON CONFLICTসিনট্যাক্সটি ব্যবহার না করেই ।


4

এটি কীভাবে কার্য সম্পাদন করবে তা ধারণা নেই তবে চেষ্টা করার অন্য বিকল্প হিসাবে, এখানে পুরানো-স্কুল পদ্ধতিতে (ব্যতীত ON CONFLICT) একই কাজ করা হচ্ছে :

WITH items (name) AS (VALUES ('foo'), ('bar'), ('zzz')),
     added        AS
      (
        INSERT INTO tag (name)

        SELECT name FROM items
        EXCEPT
        SELECT name FROM tag

        RETURNING id
      )
SELECT id FROM added

UNION ALL

SELECT id FROM tag
WHERE name IN (SELECT name FROM items)
;

এটি, tagসারণীতে পাওয়া যায় না এমন কেবলমাত্র [অনন্য] নাম সন্নিবেশ করুন এবং আইডিগুলি ফিরিয়ে দিন; tagচূড়ান্ত ফলাফলের জন্য বিদ্যমান আইডিগুলির সাথে এটি একত্রিত করুন । এছাড়াও আপনি নিক্ষেপ করতে পারেন name, যেমন আউটপুট মধ্যে ypercubeᵀᴹ দ্বারা প্রস্তাবিত , যাতে আপনি যা ID মিলের কোন নাম জানি।


1
হ্যাঁ. আমার কোডের শেষ নির্বাচনটিSELECT .. FROM ins UNION ALL SELECT ... FROM val JOIN tag ... ;
ypercubeᵀᴹ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.