2011-02-17 11 views
8

मैं उन रिकॉर्ड्स की खोज करना चाहता हूं जहां कोई विशेष फ़ील्ड या तो कुछ स्ट्रिंग के साथ शुरू होता है (मान लें "ar") या उस फ़ील्ड में स्ट्रिंग, "ar" शामिल है।एसक्यूएल कथन के WHERE खंड में भारित स्थितियां

हालांकि, मैं दो स्थितियों को अलग मानता हूं, क्योंकि मैं 10 में वापस आने वाले परिणामों की संख्या सीमित कर रहा हूं और मैं चाहता हूं कि स्थिति को स्थिति के मुकाबले ज्यादा भारित किया जाए।

उदाहरण:

SELECT * 
FROM Employees 
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%' 
LIMIT 10 

पकड़ कि है कि यदि ऐसे नाम हैं जो "ए आर" वे इष्ट किया जाना चाहिए के साथ शुरू कर रहे हैं। एकमात्र तरीका मुझे उस नाम को वापस लेना चाहिए जो केवल "ar" होता है, यदि 10 से कम नाम हैं जो "ar"

मैं एक MySQL डेटाबेस के विरुद्ध कैसे कर सकता हूं?

उत्तर

10

आपको उन्हें 2 भागों में चुनने की ज़रूरत है, और परिणामों में एक प्राथमिकता टैग जोड़ें। 10 प्रत्येक खंड से, तो उन्हें मर्ज और फिर से सबसे अच्छा 10 ले खंड 1 से 8 प्रविष्टियों, खंड 2 यूनिअन के शेष 2

SELECT * 
FROM 
(
SELECT *, 1 as Preferred 
FROM Employees 
WHERE Name LIKE 'ar%' 
LIMIT 10 
UNION ALL 
SELECT * 
FROM 
(
    SELECT *, 2 
    FROM Employees 
    WHERE Name NOT LIKE 'ar%' AND Name LIKE '%ar%' 
    LIMIT 10 
) X 
) Y 
ORDER BY Preferred 
LIMIT 10 
+0

+1। सहमत है, यह अधिक कुशल है। – mellamokb

+0

यह मेरे लिए काम करता प्रतीत होता है। क्या आप इसे बिल्कुल समझा सकते हैं?मैं समझता हूं (आम तौर पर बोल रहा हूं) संघ का क्या अर्थ है। एक्स और वाई क्या हैं और 1, 2, क्या है? –

+1

@ स्टीफन - एक्स और वाई उप-सामानों को दिए गए उपनाम हैं (प्रत्येक व्युत्पन्न तालिका को एलियाड किया जाना चाहिए - ताकि यदि आवश्यक हो तो उन्हें संदर्भित किया जा सकता है)। आप किसी भी परिणाम सेट में कॉलम जोड़ सकते हैं, केवल कॉलम और नामकरण (एलियासिंग) कॉलम देकर। इस मामले में, मैंने पहले भाग में 1 के मान के साथ "पसंदीदा" नामक एक कॉलम जोड़ा, और दूसरे भाग में 2 का मान जोड़ा। कॉलम अब परिणाम का हिस्सा है (क्वेरी आउट के लिए)। – RichardTheKiwi

4

परिणाम के लिए एक कोड मान निर्दिष्ट करें, और सॉर्ट कोड मूल्य द्वारा:

select 
    *, 
    (case when name like 'ar%' then 1 else 2 end) as priority 
from 
    employees 
where 
    name like 'ar%' or name like '%ar%' 
order by 
    priority 
limit 10 

संपादित करें:

देखें रिचर्ड उर्फ ​​एक अधिक कुशल समाधान के लिए cyberkiwi का जवाब अगर वहाँ संभावित मैचों के बहुत सारे ।

+0

से लाभ चाहिए तालिका कई मैचों मौजूद होता है तो अगर , तो यह धीमा हो सकता है क्योंकि इसे पहले सभी मैचों को प्राथमिकता देना है। – RichardTheKiwi

0

(साथ परीक्षण करने के लिए एक MySQL उदाहरण तुरंत उपलब्ध नहीं है) इस प्रयास करें:

SELECT * FROM 
    (SELECT * FROM Employees WHERE Name LIKE 'ar%' 
    UNION 
    SELECT * FROM Employees WHERE Name LIKE '%ar%' 
    ) 
LIMIT 10 

वहाँ यह करने के लिए शायद बेहतर तरीके हैं, लेकिन है कि तुरंत दिमाग में sprang।

0

मेरे समाधान सभी इच्छा उत्पाद का उत्पादन तो है:

SELECT * 
FROM Employees 
WHERE Name LIKE '%ar%' 
ORDER BY instr(name, 'ar'), name 
LIMIT 10 

instr() प्रश्न में पैटर्न की पहली घटना को देखता है। एआर% एक्सएक्सएआर से पहले आएगा।

यह रोकता है:

  1. केवल तालिका स्कैन 1 समय करना चाहिए। यूनियनों और व्युत्पन्न टेबल 3 करते हैं। कॉलम पर पहले दो पैटर्न को फ़िल्टर करने के लिए और फिर तीसरे स्थान पर सबसेट पर यह पता लगाने के लिए कि वे कहां बराबर हैं - क्योंकि संघ डुप्लिकेट करता है।

  2. पैटर्न के स्थान के आधार पर एक सही क्रम देता है। Wx> XW> xxW> आदि ...

0
SELECT * 
FROM Employees 
WHERE Name LIKE 'ar%' OR Name LIKE '%ar%' 
ORDER BY LIKE 'ar%' DESC 
LIMIT 10 

द्वारा आदेश काम करना चाहिए बाइनरी सही/की तरह के लिए झूठे और index'ed सूचकांक

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