2012-09-22 10 views
6

मैं डेटाबेस बना रहा हूं जिसमें परिणाम के लिए पिछली जगह महत्वपूर्ण है। जब मैं परिणाम के लिए पूछता हूं तो मुझे लगता है किMySQL 5.5 क्वेरी में पीछे की जगह खोने

SELECT * where `field` = 'a ' 

कोई परिणाम देता है जब कोई फ़ील्ड है जो 'ए' है। मैं परिणाम सेट में पिछली जगह पर ध्यान देना चाहता हूं। मैंने चार, वर्कर, टेक्स्ट और ब्लॉब का उपयोग करने का प्रयास किया है। मैं ध्यान दूंगा कि यह फ़ील्ड मेरी तालिका का सूचकांक है।

क्या कोई मुझे दिखा सकता है कि इस तरह से पूछताछ कैसे करें कि पिछला (और/या अग्रणी) रिक्त स्थान गिनती है? क्या मुझे यह काम करने के लिए किसी भी विशेष तरीके से अपनी तालिका को प्रारूपित करने की आवश्यकता है?

उत्तर

5

यह व्यवहार डिज़ाइन द्वारा है, न केवल MySQL में।

आप BINARY का उपयोग करके तुलना में यह आस-पास काम कर सकते हैं:

mysql> select version(), 'a' = 'a ', BINARY 'a' = BINARY 'a '; 
+-------------+------------+--------------------------+ 
| version() | 'a' = 'a ' | BINARY 'a' = BINARY 'a ' | 
+-------------+------------+--------------------------+ 
| 5.5.25a-log |   1 |      0 | 
+-------------+------------+--------------------------+ 
1 row in set (0.00 sec) 

लेकिन नहीं भी बहुत कुछ। यदि आपको व्हाइटस्पेस दिखाई देते हैं तो यह आपको SELECT एस के साथ मदद करेगा। एक खोज में उपयोगकर्ता इनपुट में; लेकिन यदि आप वास्तव में व्हाइटस्पेस-ट्राइल्ड जानकारी इनपुट करना चाहते हैं, तो यह एक समस्या होगी (आपके पास 'ए' और 'ए' दोनों के साथ एक इंडेक्स नहीं हो सकता है)।

भी

Trailing whitespace in varchar needs to be considered in comparison

देखें आप सकता है क़यास रिवर्स उस कॉलम में तार, और उन्हें वापस रिवर्स जब उन्हें प्रदर्शित करना। बेशक यह उस कॉलम के आधार पर किसी ऑर्डरिंग को तोड़ देगा, लेकिन यदि आप केवल समानता या घटते अस्तित्व का परीक्षण करते हैं, तो यह सिर्फ काम कर सकता है। अग्रणी रिक्त स्थान गिनते हैं।

समानता खोजों के लिए आप स्ट्रिंग के बेस 64 एन्कोडिंग को भी स्टोर कर सकते हैं, जिसे लेक्सिकोोग्राफिक ऑर्डर को बनाए रखना चाहिए (यानी, ए और बी के बीच ऑर्डर बेस 64 (ए) और बेस 64 (बी) के बीच बनाए रखा जाना चाहिए)। या आप स्ट्रिंग पर टर्मिनेटर जोड़ सकते हैं ("\ n" अच्छी तरह से कर सकता है और खोजों में दिखाई नहीं दे सकता है)।

अंत में

, लेकिन यह जोखिम भरा है, क्योंकि मनुष्य अंतर नहीं बता सकते हैं, आप UTF8 चार (49,824) के साथ रिक्त स्थान की जगह सकता है:

mysql> select concat ('\'a', char(49824),'\'') AS tricked, 
       concat ('\'a', ' '  ,'\'') as honest, 
       concat ('\'a', char(49824),'\'') = 
       concat ('\'a', ' '  ,'\'') as equals; 

+---------+--------+--------+ 
| tricked | honest | equals | 
+---------+--------+--------+ 
| 'a ' | 'a ' |  0 | 
+---------+--------+--------+ 
1 row in set (0.00 sec) 

पंक्तियों लगते बराबर हो, लेकिन वे नहीं कर रहे हैं । ध्यान दें कि HTML में स्थान एक स्थान है, और 49824   (nonbreaking space) है। यह उन कार्यों को प्रभावित करता है जो एचटीएमएल में परिवर्तित होते हैं, और वास्तव में एक यूटीएफ 8 कोडपॉइंट का मतलब है कि ईमानदार स्ट्रिंग दो बाइट्स है, लेकिन की लंबाई स्ट्रिंग वास्तव में तीन है।

अंत में आप VARCHAR के बजाय कॉलम VARBINARY घोषित कर सकते हैं, इस प्रकार पूरी तरह से छिपाने के लिए क्या हो रहा है। यह सबसे आसान समाधान की तरह दिखता है, लेकिन मुझे डर है कि यह आपको लाइन के नीचे कुछ हफ्तों या महीनों काट सकता है।

+0

मुझे एहसास है कि ज्यादातर परिस्थितियों में एक डीबी अग्रणी और पिछली जगहों को हटाना चाहेगा, लेकिन मेरे मामले में वे महत्वपूर्ण हैं। मेरे मामले में '' (2 रिक्त स्थान) और '' (3 रिक्त स्थान) मान्य इनपुट हैं और मुझे उनके बीच अंतर करने की आवश्यकता है, वे हैं कि मैं तालिका कैसे खोजूंगा। तो इस जानकारी के आधार पर किसी भी SQL langugaes समाधान नहीं हो सकता है? क्या मैं जो खोज रहा हूं उसे पूरा करने का कोई तरीका है? मैं mySQL में बंद नहीं हूँ। दुर्भाग्य से मेरे इनपुट में लीइंग और पीछे की जगहें हो सकती हैं। – taggedzi

+0

'ऐसे कई हैक्स संभव हैं' ... मैंने कुछ सूचीबद्ध किए हैं। दुर्भाग्यवश, कोई भी स्कॉट- या जोखिम मुक्त नहीं है। – LSerni

+0

जानकारी के लिए धन्यवाद मैं बेस 64 एन्कोडिंग का उपयोग कर सकता हूं, मैं पूरी तरह से भूल गया कि मैंने इसे कुछ समय में उपयोग नहीं किया है। धन्यवाद, मैं देखूंगा कि क्या यह काम करता है। – taggedzi

1

मुझे सफलता करने में सफलता मिली है, लेकिन मुझे यकीन नहीं है कि यह एक अस्थिर दृष्टिकोण है या नहीं।

CREATE TEMPORARY TABLE test (
    PRIMARY KEY(id), 
    id INT AUTO_INCREMENT, 
    val VARCHAR(20) 
); 

INSERT INTO test VALUES 
(NULL, 'a'), 
(NULL, 'a '), 
(NULL, 'a '), 
(NULL, 'a '); 

SELECT * FROM test 
WHERE val LIKE 'a '; 

आउटपुट

id val 
2 'a ' 

का उपयोग कहां वैल = 'एक' को ध्यान में अवांछित स्पेस लेने के बिना सभी प्रविष्टियों का चयन करेंगे, लेकिन जैसे मेरे लिए काम करता है।

+0

यह काम करता है; लेकिन फिर परीक्षण से 'चयन * का उपयोग करना तेज़ है जहां वैल = बिनरी' ए ';' ('LIKE' एक टैड धीमा है)। ओपी के दृष्टिकोण में बड़ी समस्या रखरखाव है। यह भूलना आसान है कि कुछ कॉलम गद्देदार हैं। और मुख्य समस्या (क्षेत्र प्राथमिक कुंजी है) किसी भी तरह से हल नहीं किया जाता है। अन्य परिस्थितियों में आपका यद्यपि एक त्वरित फिक्स है; इसके लिए +1। – LSerni

संबंधित मुद्दे