মাইএসকিউএল শর্তসাপেক্ষ সন্নিবেশ


99

শর্তসাপেক্ষ INSERT গঠনে আমার বেশ কষ্ট হচ্ছে

আমার কাছে কলামগুলির সাথে x_table রয়েছে (উদাহরণস্বরূপ, ব্যবহারকারী, আইটেম) যেখানে উদাহরণ আইডি অনন্য। আমি কেবলমাত্র একটি নতুন সারি সন্নিবেশ করতে চাই যদি ব্যবহারকারীটির কাছে ইতিমধ্যে কোনও প্রদত্ত আইটেম না থাকে।

উদাহরণস্বরূপ 9োকানোর চেষ্টা করছেন = 919191 ব্যবহারকারীর = 123 আইটেম = 456

Insert into x_table (instance, user, item) values (919191, 123, 456) 
    ONLY IF there are no rows where user=123 and item=456 

সঠিক দিকনির্দেশে যে কোনও সহায়তা বা দিকনির্দেশনা প্রশংসিত হবে।

উত্তর:


118

আপনার ডিবিএমএস যদি আপনি কোনও সন্নিবেশ সম্পাদন করার সময় আপনি যে টেবিলটি থেকে নির্বাচন করেন তার সীমাবদ্ধতা চাপিয়ে না দেয় তবে চেষ্টা করুন:

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE NOT EXISTS (SELECT * FROM x_table
                             WHERE user = 123 
                               AND item = 456)

এই, dualএক সারি শুধুমাত্র (মাইএসকিউএল মধ্যে Oracle এ মূলত পাওয়া যায় নি, এখন খুব) সহ একটি টেবিল। যুক্তিটি হ'ল এসইএলপেট স্টেটমেন্টটি প্রয়োজনীয় মানগুলির সাথে একক সারির ডেটা উত্পন্ন করে, তবে কেবল যখন মানগুলি ইতিমধ্যে পাওয়া যায় না।

বিকল্পভাবে, মার্জ স্টেটমেন্টটি দেখুন।


4
dualএক্ষেত্রে হাত দেওয়ার আগে কি তৈরি করা দরকার বা কোয়েরি দ্বারা একা একা বিশেষ "অস্থায়ী" টেবিল তৈরি করা হয়েছে যা কেবলমাত্র ক্যোয়ারির ব্যবহারের জন্য করা হয়েছে?
itmequinn

8
আপনার যদি dualইতিমধ্যে না থাকে তবে আপনার এটি তৈরি করা দরকার। CREATE TABLE dual ( dummy CHAR(1) DEFAULT 'x' NOT NULL CHECK (dummy = 'x') PRIMARY KEY ); INSERT INTO dual VALUES('x'); REVOKE ALL ON dual FROM PUBLIC; GRANT SELECT ON dual TO PUBLIC;
জোনাথন লেফলার

ধন্যবাদ ভয়ঙ্কর যে জানতে
itsmequinn

11
মনে রাখবেন যে, মাইএসকিউএল-তে আপনার 'ডুয়াল' নামক একটি টেবিলের সত্যিকার অর্থে উপস্থিত থাকার দরকার নেই: এটি একটি বিশেষ সারণী-নাম যা এটি থেকে যে কোনও কিছু নির্বাচন করতে ব্যবহার করা যেতে পারে।
ক্রিস্টোফার শুল্টজ

4
মাইএসকিউএল "দ্বৈত" ধারণাটি "সম্মান" করে তবে এটি আসলে বিদ্যমান না। উদাহরণস্বরূপ, আপনি SELECT COUNT(*) FROM dualযদি সর্বদা পান 1এবং SELECT 'foo' FROM dualআপনি সর্বদা পান তবে foo। তবে আপনি পারবেন না SELECT * FROM dualএবং আপনি DESCRIBE dualবা এর মতো কিছু করতে পারবেন না । আমি চেক করি নি, তবে আমিও মনে করি না আপনি অনুমতিগুলি বাতিল করতে পারেন dual, হয় না। সুতরাং এটি উল্লেখ করার মতো যে এটি আপনার প্রত্যাশার মতোই কাজ করে ... যখন তা না হয়;)
ক্রিস্টোফার শুল্টজ

52

আপনি INSERT IGNOREযখন ব্যবহারকারীর অনন্য সূচক (ব্যবহারকারী, আইটেম) আপডেট করতে বা সন্নিবেশ করানোর পরিবর্তে সন্নিবেশ সন্নিবেশকে অগ্রাহ্য করেন তাও আপনি ব্যবহার করতে পারেন ।

ক্যোয়ারীটি এর মতো দেখাবে:

INSERT IGNORE INTO x_table(instance, user, item) VALUES (919191, 123, 456)

এর সাথে আপনি অনন্য সূচকটি যুক্ত করতে পারেন CREATE UNIQUE INDEX user_item ON x_table (user, item)


4
প্রতি মাইএসকিউএল ডকুমেন্টেশন অনুযায়ী ইনসার্ট ইগনোর হ'ল প্রতিস্থাপনের প্রতিপক্ষ ... অন্তর্ভুক্ত করুন ইগনোর: পুরানো সারি রাখুন। প্রতিস্থাপন: নতুন সারি রাখুন। উভয়ই অনন্য কীতে কাজ করে।
পল কেনজোরা

সর্বকালের সেরা উত্তর
jmojico

30

আপনি কি কখনও এরকম কিছু চেষ্টা করেছেন?

INSERT INTO x_table
SELECT 919191 as instance, 123 as user, 456 as item
FROM x_table
WHERE (user=123 and item=456)
HAVING COUNT(*) = 0;

হ্যাঁ ! মাত্র একটি নির্বাচন বিবৃতি সহ স্মার্ট এবং দুর্দান্ত সমাধান
java acm

ভাল লাগল এটি প্রথম চেষ্টাতে পোস্টগ্রেকল-এর জন্য কাজ করে, যেখানে গ্রহণযোগ্য উত্তর আমার কাছে মনে হয়নি।
পাওয়ারপাইল

10

একটি সহ UNIQUE(user, item), করুন:

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=123

user=123বিট একটি "কোন সমিতি" এর সিনট্যাক্স মেলে হয় ON DUPLICATEআসলে কিছু করছেন যখন সেগুলি একই স্থান ছাড়া দফা।


4
আমি কোনও ইউনিক (ব্যবহারকারী, আইটেম) সেটআপ করতে পারছি না কারণ একই ব্যবহারকারীর এবং আইটেমের সাথে একাধিক দৃষ্টান্ত থাকতে পারে ... যখন আমি এই সন্নিবেশটি করছিলাম তখনই নয়।
অজানা

3

আপনি যদি কোনও অনন্য বাধা নির্ধারণ করতে না চান তবে এটি একটি কবজির মতো কাজ করে:

INSERT INTO `table` (`column1`, `column2`) SELECT 'value1', 'value2' FROM `table` WHERE `column1` = 'value1' AND `column2` = 'value2' HAVING COUNT(`column1`) = 0

আশা করি এটা সাহায্য করবে !


2

আপনি কি চান INSERT INTO table (...) SELECT ... WHERE ...। থেকে মাইএসকিউএল 5.6 ম্যানুয়াল

আপনার ক্ষেত্রে এটি:

INSERT INTO x_table (instance, user, item) SELECT 919191, 123, 456 
WHERE (SELECT COUNT(*) FROM x_table WHERE user=123 AND item=456) = 0

অথবা যেহেতু আপনি এই দুটি কলামের সংমিশ্রণের জন্য কী ব্যবহার করতে পারেন তা চালাতে হবে কিনা তা নির্ধারণের জন্য কোনও জটিল যুক্তি ব্যবহার করছেন না INSERTবা UNIQUEব্যবহার করতে পারেন INSERT IGNORE


তুমি কি তোমার উত্তর চালিয়েছ? আমি পেতে ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where...চলেছি (5.6.34 চলছে)
hlin117

আমার মনে হয় আপনার from dualআগে বলা দরকার where
hlin117

@ hlin117 FROM DUALকোনও টেবিলের রেফারেন্স না থাকলে মারিয়াডিবিতে ডিফল্ট হয় ( এই ডকুমেন্টেশনটি দেখুন )।
ইয়েতি

1

যদি আপনি কোনও সীমাবদ্ধতা যোগ করেন যে (x_table.user, x_table.item) অনন্য, তবে একই ব্যবহারকারী এবং আইটেমের সাথে অন্য সারি সন্নিবেশ করা ব্যর্থ হবে।

যেমন:

mysql> create table x_table ( instance integer primary key auto_increment, user integer, item integer, unique (user, item));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2),(3,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into x_table (user, item) values (1,6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2);
ERROR 1062 (23000): Duplicate entry '1-2' for key 2

এটা ঠিক না একই ব্যবহারকারীর সাথে একাধিক সারি থাকতে পারে তবে ব্যবহারকারীর আইটেমের জুটির সাহায্যে একাধিক সারি নেই।
ম্যাথু ফ্ল্যাশেন

হ্যাঁ হ্যাঁ. আমি এটি ভুল লিখেছি। জুটির প্রতিবন্ধকতা তৈরি করতে সম্পাদিত।
নিকজাইক

ভাল মন্তব্য ... আমি পিএইচপি-তে mysql_query ("INSERT") ব্যবহার করে ক্যোয়ারী চালাচ্ছি এবং মরতে পারবো বা মরতে পারো তাই ত্রুটি সম্পর্কে আমাকে সতর্ক করতে হবে যাতে আমাকে কোনও চেক করতে হবে না
অ্যাঞ্জেল.কিং ৪.4

1

আপনার ডেটা inোকানোর আগে সদৃশটি যাচাই করা ভাল, আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি নিজের কলামগুলিতে একটি অনন্য বাধা / সূচক রাখবেন যাতে কোনও ডুপ্লিকেট ডেটা ভুল করে inোকানো না যায়।


1

আপনার সমস্যা সমাধানের জন্য আপনি নিম্নলিখিত সমাধানটি ব্যবহার করতে পারেন:

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE 123 NOT IN (SELECT user FROM x_table)

যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কীভাবে এবং / বা কেন এটি সমস্যার সমাধান করে তা সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করলে উত্তরের দীর্ঘমেয়াদী মান উন্নত হবে।
নিক 3500

0

অ্যালেক্সের প্রতিক্রিয়ায় সামান্য পরিবর্তন, আপনি কেবল বিদ্যমান কলাম মানটি উল্লেখ করতে পারেন:

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=user

0

সুতরাং এটি পোস্টগ্র্রেএসকিউএল জন্য দাঁড়িয়েছে

INSERT INTO x_table
SELECT NewRow.*
FROM (SELECT 919191 as instance, 123 as user, 456 as item) AS NewRow
LEFT JOIN x_table
ON x_table.user = NewRow.user AND x_table.item = NewRow.item
WHERE x_table.instance IS NULL

0

আমি আজ জানতে পেরেছি যে একটি SELECTবিবৃতিতে কোনও WHEREশর্ত না থাকলেও FROMএবং কোনও টেবিল মোটেও না পড়লেও শর্ত থাকতে পারে ।

শর্তসাপেক্ষে এই কনস্ট্রাক্টটি ব্যবহার করে কিছু সন্নিবেশ করা খুব সহজ করে তোলে:

SELECT ... INTO @condition;
-- or if you prefer: SET @condition = ...

INSERT INTO myTable (col1, col2) SELECT 'Value 1', 'Value 2' WHERE @condition;

এটি মাইএসকিউএল 5.7 এবং মারিয়াডিবি 10.3 এ পরীক্ষিত।


-1
Insert into x_table (instance, user, item) values (919191, 123, 456) 
    where ((select count(*) from x_table where user=123 and item=456) = 0);

আপনার ডিবি এর উপর নির্ভর করে সিনট্যাক্স পরিবর্তিত হতে পারে ...


4
এটা কি জন্য? মাইএসকিউএল?
উমায়ের এ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.