FIND_IN_SET () বনাম IN ()


125

আমার ডাটাবেসে আমার 2 টি টেবিল রয়েছে। একটি আদেশের জন্য, এবং একটি কোম্পানির জন্য।

অর্ডারগুলির এই কাঠামো রয়েছে:

OrderID     |     attachedCompanyIDs
------------------------------------
   1                     1,2,3
   2                     2,4

এবং কোম্পানির এই কাঠামো রয়েছে:

CompanyID      |        name
--------------------------------------
    1                 Company 1
    2                 Another Company
    3                 StackOverflow
    4                 Nothing

অর্ডার সংস্থাগুলির নাম পেতে, আমি এই জাতীয় একটি কোয়েরি করতে পারি:

SELECT name FROM orders,company
WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)

এই ক্যোয়ারীটি ঠিকঠাক কাজ করে, তবে নিম্নলিখিত কোয়েরিটি কার্যকর করে না।

SELECT name FROM orders,company
WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)

প্রথম ক্যোয়ারী দ্বিতীয়টি নয় কেন কাজ করে?

প্রথম ক্যোয়ারী ফেরত:

name
---------------
Company 1
Another Company
StackOverflow

দ্বিতীয় ক্যোয়ারী কেবল ফেরত দেয়:

name
---------------
Company 1

এটি কেন, প্রথম ক্যোয়ারী সমস্ত সংস্থাকে ফেরত দেয় কেন, তবে দ্বিতীয় ক্যোয়ারী কেবল প্রথমটিকে ফেরত দেয়?


3
সংযুক্তকম্পিনিআইডিগুলি একটি বড় স্ট্রিং, সুতরাং
মাইএসকিএল

আমি মনে করি এটি সেরা উদাহরণ mysqltutorial.org/mysql-find_in_set
শুরভির মরি

উত্তর:


100
SELECT  name
FROM    orders,company
WHERE   orderID = 1
        AND companyID IN (attachedCompanyIDs)

attachedCompanyIDsএটি একটি স্কেলার মান যা INT(টাইপের companyID) মধ্যে ফেলে দেওয়া হয় ।

Castালাই কেবল প্রথম অ-অঙ্ক (আপনার ক্ষেত্রে কমা) পর্যন্ত সংখ্যাগুলি ফেরত দেয়।

সুতরাং,

companyID IN ('1,2,3')  companyID IN (CAST('1,2,3' AS INT))  companyID IN (1)

ইন PostgreSQL, আপনি অ্যারেতে স্ট্রিংটি কাস্ট করতে পারেন (বা এটি প্রথম স্থানে অ্যারে হিসাবে সঞ্চয় করতে পারেন):

SELECT  name
FROM    orders
JOIN    company
ON      companyID = ANY (('{' | attachedCompanyIDs | '}')::INT[])
WHERE   orderID = 1

এবং এটি এমনকি একটি সূচক ব্যবহার করবে companyID

দুর্ভাগ্যক্রমে, MySQLএটি পরে কাজ করে না কারণ পরবর্তীরা অ্যারেগুলিকে সমর্থন করে না work

আপনি এই নিবন্ধটি আকর্ষণীয় মনে করতে পারেন (দেখুন #2):

হালনাগাদ:

কমা দ্বারা বিচ্ছিন্ন তালিকার মানগুলির সংখ্যার বিষয়ে যদি কিছু যুক্তিসঙ্গত সীমা থাকে (তবে এর চেয়ে বেশি কিছু বলুন না 5), সুতরাং আপনি এই কোয়েরিটি ব্যবহার করার চেষ্টা করতে পারেন:

SELECT  name
FROM    orders
CROSS JOIN
        (
        SELECT  1 AS pos
        UNION ALL
        SELECT  2 AS pos
        UNION ALL
        SELECT  3 AS pos
        UNION ALL
        SELECT  4 AS pos
        UNION ALL
        SELECT  5 AS pos
        ) q
JOIN    company
ON      companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED)

3
ব্যাখ্যার জন্য ধন্যবাদ. আমি বুঝতে পারিনি যে সংযুক্ত কম্পিউটারের ক্ষেত্রগুলি একটি আইএনটিতে ছড়িয়ে দেওয়া হয়েছিল। মাইএসকিউএলে এর আশেপাশে কোনও উপায় আছে? FIND_IN_SETকাজ করে, তবে সূচী ব্যবহার করে না, এবং সংস্থার সারণীতে প্রচুর তথ্য সহ ধীর হতে পারে।
রকেট হাজমত

1
আপনি কি সেই আপডেট ব্যাখ্যা করতে পারেন? এটি ঠিক কী করে, কারণ এটি কাজ করে বলে মনে হয়।
রকেট হাজমত

1
@ রকেট: এটি posশুরু থেকে আইটেমগুলি সরিয়ে দেয় এবং বাকীটিকে CVSপূর্ণসংখ্যায় ফেলে দেয়।
কাসনসুই

9
10 things in MySQL (that won’t work as expected)
থাম্বস

@ কোসনোই, আপনি লেখেন কেন CROSS JOIN? তারা কি মাইএসকিউএলে একই নয় ?
পেসারিয়ার

13

সংযুক্তকম্পানিআইডিগুলি একটি বড় স্ট্রিং, সুতরাং মাইএসকিএল এটির জন্য এটির পূর্ণসংখ্যাতে সংস্থাটি অনুসন্ধান করার চেষ্টা করবে

যখন আপনি যেখানে ব্যবহার করবেন

সুতরাং যদি কোম্পনিড = 1:

companyID IN ('1,2,3')

এটি সত্য প্রত্যাবর্তন

তবে যদি 1 নম্বরটি প্রথম স্থানে না থাকে

 companyID IN ('2,3,1')

এর প্রত্যাবর্তন মিথ্যা


3

সমস্ত সম্পর্কিত সংস্থার নাম পেতে, নির্দিষ্ট আইডির ভিত্তিতে নয়।

SELECT 
    (SELECT GROUP_CONCAT(cmp.cmpny_name) 
    FROM company cmp 
    WHERE FIND_IN_SET(cmp.CompanyID, odr.attachedCompanyIDs)
    ) AS COMPANIES
FROM orders odr

1

কারণ দ্বিতীয় ক্যোয়ারী আইডির 1 বা 2 বা 3 এর সাথে সারি সন্ধান করছে, প্রথম ক্যোয়ারী কোম্পানির আইডিতে বিদ্যমান কমা বিস্মৃত মানগুলির মধ্যে একটির সন্ধান করছে,

এবং এখানে আরেকটি সমস্যা হ'ল আপনি নিজের কমন কীতে টেবিলগুলিতে যোগ দিচ্ছেন না যাতে আপনি সারিগুলির একটি মিউটেশন পেতে যাচ্ছেন = গণনা (টেবিল 1) * গণনা (টেবিল 2);

আপনার উত্তরটি আমার উত্তরের অংশ 2 সহ সত্যই বিদ্যমান। (আপনার দ্বিতীয় প্রশ্নের সাথে)


আমি দেখানোর চেয়ে উভয় সারণীতে আরও সারি রয়েছে। উভয় টেবিলের মধ্যে, আপনি যে লগ ইন করেছেন সেটির আইডি কি সেই সহায়তায় যোগদান করবে?
রকেট হাজমত

ভাল যদি আপনার প্রথম ক্যোয়ারী প্রত্যাশিত ফলাফলগুলি না ফিরিয়ে দেয় তবে আপনাকে কেবল কিছু পরিবর্তন করতে হবে। যদি প্রথম ক্যোয়ারী আপনি যে ফলাফলগুলি চান তা ফিরিয়ে দিচ্ছে তবে সত্যিই কোনও সমস্যা নেই। আমি ভেবেছিলাম যে আপনি কেবল কৌতূহলী ছিলেন কেন 2 জন একই ফলাফল দেখায় না।
সুপারফ্রো

@ সুফফ্রো, আমি কেন আগ্রহী যে 2 জন একই ফলাফল কেন দেখায় না?
রকেট হাজমত

আপনার দ্বিতীয় ক্যোয়ারী একটি যেখানে IN (মান) ব্যবহার করছে যেখানে 'মানগুলি' অংশটি টেবিল থেকে আসে এবং এটির স্ট্রিং। স্ট্রিংটিকে বুল ট্রু হিসাবে মূল্যায়ন করা হচ্ছে যা = 1 যার ফলে এটি কেবল প্রথম সারিটি দেখায়।
সুপারফ্রো

1
আপনি যদি কর্মক্ষমতা সম্পর্কে চিন্তিত হন তবে আপনার সম্ভবত আপনার ডাটাবেস কাঠামোটি পরিবর্তন করার বিষয়ে চিন্তা করা উচিত। আপনি অর্ডার সারণীতে কমা বিস্মৃত তালিকাটি ব্যবহার না করে 2 টি মান, অর্ডার_আইডি এবং সংস্থা_আইডি সমন্বিত একটি যৌথ টেবিল যুক্ত করতে পারেন। এটি আপনাকে সংস্থা থেকে নাম নির্বাচন করতে অনুমতি দেবে এটি সূচকগুলি ব্যবহার করবে।
সুপারফ্রো

-1

আমাকে কখন FIND_IN_SET ব্যবহার করতে হবে এবং কখন IN ব্যবহার করতে হবে তা আমাকে ব্যাখ্যা করতে দিন।

আসুন টেবিল এ নিয়ে আসুন যার "কমান্ড", "অ্যানাম" নামে কলাম রয়েছে। আসুন টেবিল বি নেওয়া যাক যেখানে "বিড", "নাম", "এইডস" নামে কলাম রয়েছে।

নীচের মত সারণি এ এবং সারণি বিতে এখন ডামি মান রয়েছে।

টেবিল এ

সহায়তা aname

1 আপেল

2 কলা

3 আমের

টেবিল বি

বিড নামকরণ এইডস

1 আপেল 1,2

2 কলা 2,1

3 আম 3,1,2

enter code here

কেস 1: আপনি যদি টেবিল বি থেকে এই রেকর্ডগুলি পেতে চান যা অ্যাডস কলামগুলিতে 1 টি মান উপস্থিত থাকে তবে আপনাকে FIND_IN_SET ব্যবহার করতে হবে।

ক্যোয়ারী: এফআইএনএএন বি এফআইএনএইএন বি থেকে নির্বাচন করুন (এএইড, বি। এড) যেখানে এএইড = 1;

কেস 2: আপনি যদি এই রেকর্ডগুলি টেবিলের থেকে পেতে চান যার 1 বা 2 বা 3 মান সহায়তার কলামগুলিতে উপস্থিত থাকে তবে আপনাকে IN ব্যবহার করতে হবে।

প্রশ্ন: এ-জয়েন বি ও এএইড ইন (বি.এইডস) থেকে * নির্বাচন করুন;

এখন এখানে আপনার কাছে যা আপনার মাইএসকিএল কোয়েরির মাধ্যমে প্রয়োজন needs


এই প্রশ্নটি ইতিমধ্যে সমাধান করা হয়েছিল। এছাড়াও আমি মনে করি না যে আপনার দ্বিতীয় উদাহরণটি, আইএন সহ, কাজ করে ... এটি মূলত আমি সমস্যাটি শুরুতে সমাধান করার চেষ্টা করছিলাম।
রকেট হাজমত

-2
SELECT o.*, GROUP_CONCAT(c.name) FROM Orders AS o , Company.c
    WHERE FIND_IN_SET(c.CompanyID , o.attachedCompanyIDs) GROUP BY o.attachedCompanyIDs

6
তাই আপনাকে স্বাগতম! ব্যাখ্যা ছাড়াই কোড খুব কমই সহায়ক। এই ক্ষেত্রে এটি "কেন ...?" প্রশ্নের উত্তর দেওয়ার চেষ্টা করে না। এছাড়াও দয়া করে নোট করুন যে এই নির্দিষ্ট প্রশ্নের ইতিমধ্যে একটি স্বীকৃত উত্তর রয়েছে যা একটি ভাল প্রাপ্ত (> ৮০ ভোট!) উত্তর দেয়। একজন নতুন ব্যবহারকারী হিসাবে উত্তর না দেওয়া প্রশ্ন এবং / অথবা নিজেই ভাল প্রশ্ন জিজ্ঞাসা করার দিকে মনোনিবেশ করা ভাল।
সিএফআই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.