2012-07-28 7 views
10

2 तालिकाओं की तरह नीचेमाइस्क्ल इनर या शर्त के साथ शामिल हो?

location_distance

---------------------------------------------- 
id | fromLocid | toLocid | distance 
---------------------------------------------- 
1 | 3   | 5  | 70 
2 | 6   | 8  | 15 
3 | 2   | 4  | 63 
... 

other_table

-------------------------------------------- 
Id | fromLocid | toLocid | otherdata 
-------------------------------------------- 
12 | 5   | 3   | xxxx 
22 | 2   | 4   | xxxx 
56 | 8   | 6   | xxxx 
78 | 3   | 5   | xxxx 

मैं दूरी पुनः प्राप्त करने के प्रत्येक पंक्ति के लिए other_table में स्थानों डब्ल्यू/b करना चाहते हैं। यहां मैंने कोशिश की है कि मैंने

SELECT ot.*, ld.distance FROM other_table AS ot 
    INNER JOIN location_distance ld ON ld.fromLocid = ot.fromLocid AND ld.toLocid = ot.toLocid 

यह स्थान पंक्तियों को वापस नहीं करता है यदि स्थान मान इसके विपरीत हैं। अपेक्षित परिणाम उत्पन्न करने के लिए उपरोक्त क्वेरी को मैं कैसे लिख सकता हूं? क्या मुझे शामिल होने वाले खंड पर या स्थिति शामिल करनी चाहिए? नीचे की तरह?

SELECT ot.*, ld.distance FROM other_table AS ot 
    INNER JOIN location_distance ld ON (ld.fromLocid = ot.fromLocid OR ld.fromLocid = ot.toLocid) AND (ld.toLocid = ot.fromLocid OR ld.toLocid = ot.fromLocid) 

लेकिन इस क्वेरी के बारे में बताएं कहते हैं, "रेंज प्रत्येक रिकॉर्ड के लिए जाँच की"। क्या यह एक बुरा अभ्यास है?

परिणाम

-------------------------------------------------------- 
Id | fromLocid | toLocid | otherdata | distance 
-------------------------------------------------------- 
22 | 2  | 4  | xxxx  | 63 
78 | 3  | 5  | xxxx  | 70 

अपेक्षित परिणाम होना चाहिए

----------------------------------------------------- 
Id | fromLocid | toLocid | otherdata | distance 
----------------------------------------------------- 
12 | 5   | 3  | xxxx  | 70 
22 | 2   | 4  | xxxx  | 63 
56 | 8   | 6  | xxxx  | 15 
78 | 3   | 5  | xxxx  | 70 
+0

आपने पहले से ही अपने प्रश्न – Andreas

+0

का उत्तर दिया है, लेकिन वह दूसरी क्वेरी कहती है "प्रत्येक रिकॉर्ड के लिए रेंज की जांच की गई"। क्या यह एक बुरा अभ्यास है? – jane

+0

प्रति से नहीं; mysql सिर्फ आपको बता रहा है कि यह रेंज एक्सेस विधि का उपयोग करता है जिसका अर्थ है कि "यह उपयोग करने के लिए कोई अच्छी अनुक्रमणिका नहीं है" (http://dev.mysql.com/doc/refman/5.1/en/explain-output.html) ", जो वास्तव में या के कारण है। – Andreas

उत्तर

1

यह शायद की तरह दो बार दूरी तालिका में शामिल होने के लिए तेजी से हो जाएगा

INNER JOIN location_distance ld1 ON ld1.fromLocid = ot.fromLocid AND ld1.toLocid = ot.toLocid 
INNER JOIN location_distance ld2 ON ld2.toLocid = ot.fromLocid AND ld2.fromLocid = ot.toLocid 

और उसके बाद जो एक का चयन करने

IF(ld1.fromLocid, ld1.distance, ld2.distance) as distance 
+0

धन्यवाद, यह एक कोशिश करेगा – jane

6

आप दो बार एक LEFT JOIN का उपयोग कर location_distance मेज पर शामिल हो सकते हैं निर्धारित करने के लिए एक यदि का उपयोग और उसके बाद COALESCE() फ़ंक्शन का उपयोग distance के लिए सही मान वापस जाने के लिए:

select ot.id, 
    ot.fromlocid, 
    ot.tolocid, 
    ot.otherdata, 
    coalesce(ld1.distance, ld2.distance) distance 
from other_table ot 
left join location_distance ld1 
    on ld1.fromLocid = ot.toLocid 
    and ld1.toLocid = ot.fromLocid 
left join location_distance ld2 
    on ld2.toLocid = ot.toLocid 
    and ld2.fromLocid = ot.fromLocid 

देखें SQL Fiddle with Demo

यह परिणाम देता है:

| ID | FROMLOCID | TOLOCID | OTHERDATA | DISTANCE | 
--------------------------------------------------- 
| 12 |   5 |  3 |  xxxx |  70 | 
| 22 |   2 |  4 |  xxxx |  63 | 
| 56 |   8 |  6 |  xxxx |  15 | 
| 78 |   3 |  5 |  xxxx |  70 | 
संबंधित मुद्दे