মাইএসকিউএল ক্যোয়ারী কমা দ্বারা পৃথক স্ট্রিংয়ের মান সন্ধান করছে


93

COLORS (varchar(50))আমার টেবিলে আমার একটি ক্ষেত্র SHIRTSরয়েছে যাতে কমা বিস্মৃত স্ট্রিং রয়েছে 1,2,5,12,15,। প্রতিটি সংখ্যা উপলব্ধ রঙের প্রতিনিধিত্ব করে।

select * from shirts where colors like '%1%'সমস্ত লাল শার্ট (রঙ = 1) পেতে কোয়েরি চালানোর সময় , আমি এমন শার্টগুলিও পাই যার রঙ ধূসর (= 12) এবং কমলা (= 15)।

আমি কীভাবে ক্যোয়ারীটি পুনরায় লেখব যাতে এটি শুধুমাত্র 1 টি রঙ নির্বাচন করে এবং 1 নম্বরযুক্ত সমস্ত রঙ নয়?


6
আমি মনে করি আপনি রেইগেক্সের মাধ্যমে এটি করতে পারতেন তবে এর চেয়ে আরও ভাল সমাধান হ'ল শার্টের রঙগুলি আলাদা টেবিল (রঙ) এ ভাগ করা এবং সংযুক্ত টেবিল (শার্ট_ রঙ) সাথে সংযোগের জন্য রঙ / শার্টের আইডি ব্যবহার করুন।
সেজেজোজ

আমি 6 টি উত্তর দিয়ে বিশ্বাস করতে পারছি না তাদের মধ্যে কেউই মাইএসকিউএল এর সেট ডাটা টাইপের উল্লেখ করেনি ..
কলিনম

উত্তর:


190

ক্লাসিক উপায়টি হ'ল বাম এবং ডানদিকে কমা যোগ করা:

select * from shirts where CONCAT(',', colors, ',') like '%,1,%'

তবে Find_in_set এছাড়াও কাজ করে:

select * from shirts where find_in_set('1',colors) <> 0

আমি সন্ধান_ইন_সেট চেষ্টা করেছিলাম তবে আমি যে রঙের মানটি প্রবেশ করিয়ে দিই না কেন তা একই ফলাফলটি দেয় ... কোনও পরামর্শ?
বাইকাইক 77

@ বাইকআই ​​:77: হতে পারে এটিই সমস্যা, ডকুমেন্টেশন বলছে: প্রথম যুক্তিতে কমা (",") চরিত্র থাকলে এই ফাংশনটি সঠিকভাবে কাজ করে না।
Andomar

আমার ভুল, এটি একই ডামি মানগুলির কারণে একটি যৌক্তিক ভুল ছিল। এটা ভাল কাজ করে। ধন্যবাদ!
বাইকাইক 77

@ অ্যান্ডোমার আমি আপনার উত্তরটি খুঁজে পাওয়ার আগে আমি IN এর সাথে লড়াই করছি না তবে আপনার মনোযোগের মতো কাজ হচ্ছে ... আপনাকে অনেক ধন্যবাদ ..
পিএইচপি মেন্টর

4
Find_in_set এর সূচকটি ব্যবহার না করায় এটির পারফরম্যান্সের প্রভাব রয়েছে
কামরান শহীদ



12

এটি নিশ্চিতভাবে কাজ করবে এবং আমি আসলে এটি ব্যবহার করে দেখেছি:

lwdba@localhost (DB test) :: DROP TABLE IF EXISTS shirts;
Query OK, 0 rows affected (0.08 sec)

lwdba@localhost (DB test) :: CREATE TABLE shirts
    -> (<BR>
    -> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> ticketnumber INT,
    -> colors VARCHAR(30)
    -> );<BR>
Query OK, 0 rows affected (0.19 sec)

lwdba@localhost (DB test) :: INSERT INTO shirts (ticketnumber,colors) VALUES
    -> (32423,'1,2,5,12,15'),
    -> (32424,'1,5,12,15,30'),
    -> (32425,'2,5,11,15,28'),
    -> (32426,'1,2,7,12,15'),
    -> (32427,'2,4,8,12,15');
Query OK, 5 rows affected (0.06 sec)
Records: 5  Duplicates: 0  Warnings: 0

lwdba@localhost (DB test) :: SELECT * FROM shirts WHERE LOCATE(CONCAT(',', 1 ,','),CONCAT(',',colors,',')) > 0;
+----+--------------+--------------+
| id | ticketnumber | colors       |
+----+--------------+--------------+
|  1 |        32423 | 1,2,5,12,15  |
|  2 |        32424 | 1,5,12,15,30 |
|  4 |        32426 | 1,2,7,12,15  |
+----+--------------+--------------+
3 rows in set (0.00 sec)

একবার চেষ্টা করে দেখো !!!


আরে @landlandomysqldba, আমি আপনার ক্যোয়ারীটি পরীক্ষা করি এবং এটি ঠিক কাজ করে তবে আমার এতে কিছু পরিবর্তন করা দরকার। আসুন আমি কলামে রঙের মান 1,2 থাকা সমস্ত শার্ট পেতে চাইলে বলি।
আহসান

7

রঙগুলির সেটটি যদি কম বা কম স্থির হয় তবে সবচেয়ে কার্যকর এবং সবচেয়ে পঠনযোগ্য উপায়টি হ'ল আপনার অ্যাপ্লিকেশনটিতে স্ট্রিং ধ্রুবক ব্যবহার করা এবং তারপরে আপনার প্রশ্নের SETসাথে মাইএসকিউএল টাইপ ব্যবহার করা FIND_IN_SET('red',colors)FIND_IN_SETSET সহ প্রকারটি ব্যবহার করার সময় , মাইএসকিউএল সমস্ত মান সংরক্ষণ করতে একটি পূর্ণসংখ্যার ব্যবহার করে এবং কমা-বিচ্ছিন্ন স্ট্রিংয়ের স্ক্যান করার চেয়ে মানগুলির উপস্থিতি যাচাইয়ের জন্য বাইনারি "and"অপারেশন ব্যবহার করে ।

ইন SET('red','blue','green'), 'red'অভ্যন্তরীণভাবে হিসাবে সংরক্ষিত হবে 1, 'blue'যেমন অভ্যন্তরীণভাবে সংরক্ষণ করা হবে 2এবং 'green'যেমন অভ্যন্তরীণভাবে সঞ্চয় করতে পারা যাবে 4। মান 'red,blue'হিসাবে সংরক্ষিত হবে 3( 1|2) এবং 'red,green'যেমন 5( 1|4)।


3

আপনি যদি মাইএসকিউএল ব্যবহার করে থাকেন তবে এমন একটি পদ্ধতি রয়েছে রেগেক্স যা আপনি ব্যবহার করতে পারেন ...

http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp

তাহলে আপনি ব্যবহার করবেন:

SELECT * FROM `shirts` WHERE `colors` REGEXP '\b1\b'

এটি সনাক্ত করতে পারিনি, যদিও আমি নিশ্চিত যে এটি আমার দোষ। ধন্যবাদ এক মিল সাথী।
বাইকাইক 77

3

আপনার প্রকৃতপক্ষে আপনার ডাটাবেস স্কিমাটি ঠিক করা উচিত যাতে আপনার তিনটি সারণী থাকে:

shirt: shirt_id, shirt_name
color: color_id, color_name
shirtcolor: shirt_id, color_id

তারপরে আপনি যদি লাল রঙের সমস্ত শার্টগুলি সন্ধান করতে চান তবে আপনি একটি কোয়েরি করবেন:

SELECT *
FROM shirt, color
WHERE color.color_name = 'red'
  AND shirt.shirt_id = shirtcolor.shirt_id
  AND color.color_id = shirtcolor.color_id

8
@ ব্লিন্ডি: এটি কেবল সত্য যদি আপনি ধরে নেন যে ওপিতে ডেটাবেস স্কিমায় অধিকার সম্পাদনা রয়েছে; ডাটাবেসটিকে নতুন করে ডিজাইন করার, ডেটা মাইগ্রেট করার এবং সমস্ত ক্লায়েন্টের রিফ্যাক্টারের সময় রয়েছে; এবং এই প্রশ্নের জন্য জটিলতা হ্রাস অ্যাপ্লিকেশন বাকী জটিলতা বৃদ্ধি ছাড়িয়ে যায়।
Andomar

4
@ অ্যান্ডোমার, তারপরে আবার যখন তিনি সারি পুনরুদ্ধারগুলির জন্য আকার সীমাবদ্ধতায় চলে যাবেন এবং তার "রেকর্ডগুলি" ক্লিপ হয়ে যাবে, আসল মজাটি কখন শুরু হবে!
অন্ধ 21

4
@ ব্লিনডি: আপনি বিন্দুটি মিস করছেন; আমি যুক্তি দিচ্ছি না যে তাঁর সর্বোত্তম সমাধান রয়েছে, কেবল যে তার পরিবেশকে তার পছন্দ অনুসারে নতুন করে ডিজাইনের স্বাধীনতা নেই
Andomar

আমি @ অ্যান্ডোমার
অ্যাডাম বি এর


0

1. মাইএসকিউএল এর জন্য:

SELECT FIND_IN_SET(5, columnname) AS result 
FROM table

2. পোস্টগ্রিস এসকিউএল জন্য:

SELECT * 
FROM TABLENAME f
WHERE 'searchvalue' = ANY (string_to_array(COLUMNNAME, ','))

উদাহরণ

select * 
from customer f
where '11' = ANY (string_to_array(customerids, ','))

0

আপনি নিম্নলিখিত ফাংশন দ্বারা এটি অর্জন করতে পারেন।

ফাংশন তৈরি করতে নিম্নলিখিত কোয়েরি চালান।

DELIMITER ||
CREATE FUNCTION `TOTAL_OCCURANCE`(`commastring` TEXT, `findme`     VARCHAR(255)) RETURNS int(11)
NO SQL
-- SANI: First param is for comma separated string and 2nd for string to find.
return ROUND (   
    (
        LENGTH(commastring)
        - LENGTH( REPLACE ( commastring, findme, "") ) 
    ) / LENGTH(findme)        
);

এবং এই ফাংশন কল করুন

msyql> select TOTAL_OCCURANCE('A,B,C,A,D,X,B,AB', 'A');

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