यदि स्ट्रिंग सम्‍मिलित है, तो Postgresql का चयन करें


105

तो मैं अपने Postgresql में एक:

TAG_TABLE
==========================
id            tag_name       
--------------------------
1             aaa
2             bbb
3             ccc

मेरी समस्या को सरल बनाने के लिए, मैं क्या करना चाहता हूं TAG_TABLE से 'आईडी' का चयन करें जब एक स्ट्रिंग "आआआआआ" में 'टैग_नाम' हो। तो आदर्श रूप में, इसे केवल "1" वापस करना चाहिए, जो टैग नाम 'आ' के लिए आईडी है

यह वही है जो मैं अभी तक कर रहा हूं:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'

लेकिन जाहिर है, यह काम नहीं करता है, क्योंकि पोस्टग्रेट्स सोचते हैं कि '% tag_name%' का मतलब उस कॉलम के तहत वास्तविक डेटा मान के बजाय 'tag_name' के विकल्प वाला एक पैटर्न है।

मैं पैटर्न में tag_name कैसे पास करूँ ??

जवाबों:


131

आपको उद्धरण के बाहर 'tag_name' का उपयोग करना चाहिए; फिर इसकी व्याख्या रिकॉर्ड के क्षेत्र के रूप में की गई। कॉनटेनटेट यूज़ '' || शाब्दिक प्रतिशत संकेतों के साथ:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || tag_name || '%';

5
जब टैग_नाम है, तो क्या है "; drop table TAG_TABLE; --"?
डेनिस डे बर्नार्डी

24
@ डेनिस: कुछ नहीं होता। आपको कोई पंक्ति नहीं मिलती है, क्योंकि WHEREखंड का मूल्यांकन होता है FALSE। बयान गतिशील नहीं है, केवल मानों को समाप्‍त किया गया है, SQL इंजेक्शन के लिए कोई मौका नहीं।
इरविन ब्रान्डेसटेटर

1
आआआ और टैग_नाम का क्रम उल्टा नहीं होना चाहिए? मेरा मतलब है कि आपको एक कॉलम नाम रखना चाहिए जहां
user151496

@ user151496 इसलिए नहीं कि पैटर्न को LIKEकीवर्ड के दाईं ओर जाना है ।
jpmc26

4
LIKEजब उन चर में अंडरस्कोर (_) या प्रतिशत वर्ण (%) होते हैं, तो पैटर्न में चर का उपयोग करने से अनपेक्षित परिणाम हो सकते हैं। इस फ़ंक्शन के साथ, उदाहरण के लिए, इन पात्रों से बचना आवश्यक हो सकता है: CREATE OR REPLACE FUNCTION quote_for_like(text) RETURNS text LANGUAGE SQL IMMUTABLE AS $$ SELECT regexp_replace($1, '([\%_])', '\\\1', 'g'); $$;(Freenode पर #postgresql IRC चैनल से उपयोगकर्ता MatheusOl से)।
मार्टिन वॉन विटिच

46

मैं व्यक्तिगत रूप से ~ ऑपरेटर के सरल सिंटैक्स को पसंद करता हूं।

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' ~ tag_name;

अंतर को समझने के लिए Lgr और ~ के बीच अंतर के माध्यम से पढ़ने लायक । `


2
यह तभी काम करता है जब tag_nameएक उचित REGEX हो। बहुत जोखिम भरा है।
जैकब फेडिकज़क

@JakubFedyczak शाब्दिक टैग_नाम से मेल खाने के लिए ***=जिसका उपयोग आप postgresql.org/docs/current/static/functions-matching.html में करते हैं । हालाँकि मैंने पाया है कि strpos/ positionसमाधानों की तुलना में बहुत अधिक धीमा होना ।
फन्नेहे

27

एक विकल्प के लिए खोज करने का एक उचित तरीका अभिव्यक्ति के positionबजाय फ़ंक्शन का उपयोग करना है like, जिसके लिए भागने की आवश्यकता है %, _और एक भागने चरित्र ( \डिफ़ॉल्ट रूप से):

SELECT id FROM TAG_TABLE WHERE position(tag_name in 'aaaaaaaaaaa')>0;

ऐसा करने का यह सही तरीका है। किसी को भी हैकी रेगेक्स दृष्टिकोण का उपयोग नहीं करना चाहिए।
खोल

LIKEऔर सूचकांकों का ILIKEउपयोग कर सकते हैं ginpositionनही सकता।
यूजीन पखोमोव

14

समाधान के अलावा 'aaaaaaaa' LIKE '%' || tag_name || '%'वहाँ position(args के उलट क्रम) कर रहे हैं और strpos

SELECT id FROM TAG_TABLE WHERE strpos('aaaaaaaa', tag_name) > 0

इसके अलावा जो अधिक कुशल है (LIKE कम कुशल दिखता है, लेकिन एक इंडेक्स चीज़ों को बदल सकता है), LIKE के साथ एक बहुत ही मामूली समस्या है: tag_name बिल्कुल नहीं होना चाहिए %और विशेष रूप से _(सिंगल चार वाइल्डकार्ड), कोई गलत सकारात्मकता देने के लिए नहीं।


2
मुझे स्थिति के साथ स्ट्रैप को बदलना था, जैसा कि स्ट्रैप हमेशा 0 मेरे लिए लौटा
जेसीएफ

-2
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || "tag_name" || '%';

tag_name उद्धरण में होना चाहिए अन्यथा यह त्रुटि देगा क्योंकि tag_name doest मौजूद नहीं है


2
यह स्वीकृत उत्तर के बिल्कुल विपरीत है । आप इसे स्ट्रिंग के रूप में संक्षिप्त कर रहे हैं, जबकि इसे एक स्तंभ होने की आवश्यकता है ...
सूरज राव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.