2008-12-29 1 views
8

यह संभव है कि इस तरह के एक प्रश्न से पहले पूछा गया है, लेकिन मैं खोजने के लिए शर्तों के बारे में नहीं सोच सकता।एसक्यूएल विशेष पंक्ति के आसपास "विंडो" का चयन करना

मैं एक फोटो गैलरी एप्लिकेशन पर काम कर रहा हूं, और वर्तमान तस्वीर के संदर्भ को दिखाते हुए 9 थंबनेल प्रदर्शित करना चाहता हूं (केंद्र में वर्तमान तस्वीर के साथ 3x3 ग्रिड में, जब तक कि वर्तमान तस्वीर पहले में न हो 4 फोटो दिखाए जा रहे हैं, इस मामले में यदि उदाहरण के लिए यदि वर्तमान तस्वीर दूसरी है तो मैं फोटो 1 से 9 का चयन करना चाहता हूं)।

1, 5, 9, 12, 13, 18, 19, 20, 21, 22, 23, 25, 26

तो वर्तमान: उदाहरण के लिए, आईडी के साथ तस्वीरों की सूची से युक्त एक एल्बम दिया तस्वीर 19 है, मैं चाहता हूँ भी देखने के लिए:

9, 12, 13, 18, 19, 20, 21, 22, 23

वर्तमान तस्वीर 5 है, तो मैं भी देखना चाहते:

1, 5, 9, 12, 13, 18, 1 9, 20, 21

मैं की तर्ज पर कुछ के बारे में सोच कर दिया गया है:

SELECT * 
FROM photos 
WHERE ABS(id - currentphoto) < 5 
ORDER BY id ASC 
LIMIT 25 

लेकिन इस मामले जहां आईडी गैर अनुक्रमिक हैं में काम नहीं करता है (उपरोक्त उदाहरण के रूप में), या जहां मामले के लिए Currentphoto से पहले अपर्याप्त तस्वीरें हैं।

कोई विचार?

धन्यवाद,

Dom

पी.एस. अगर कुछ अस्पष्ट है तो कृपया एक टिप्पणी छोड़ दें, और मैं इस सवाल को स्पष्ट करूंगा। यदि कोई अन्य लोगों को भविष्य में इस प्रश्न को खोजने में मदद करने के लिए एक और उपयोगी शीर्षक के बारे में सोच सकता है, तो कृपया भी टिप्पणी करें।

उत्तर

5

शायद सिर्फ एक यूनिअन इस्तेमाल कर सकते हैं, और फिर प्रक्रियात्मक कोड है कि परिणाम प्रदर्शित करता है (जैसा कि इस गैर बढ़त मामलों में 20 पंक्तियों वापस आ जाएगी) में अतिरिक्त परिणाम बंद ट्रिम:

(SELECT 
    * 
FROM photos 
    WHERE ID < #current_id# 
    ORDER BY ID DESC LIMIT 10) 
UNION 
    (SELECT * 
    FROM photos 
    WHERE ID >= #current_id# 
    ORDER BY ID ASC LIMIT 10) 
ORDER BY ID ASC 

संपादित करें: सीमा के रूप में dorfier le ने सुझाव दिया, संघ के दोनों किनारों पर 10 तक पहुंच गई।

संपादित 2: डॉमिनिक द्वारा सुझाए गए अंतिम कार्यान्वयन को बेहतर ढंग से प्रतिबिंबित करने के लिए संशोधित।

+1

यह एक अच्छी, उपयोगी तकनीक है। मैंने इसे अतीत में MySQL के साथ उपयोग किया है। सूची के सिरों को संभालने के लिए, जहां आपके पास पर्याप्त पंक्तियां नहीं होंगी: LIMIT 10 का उपयोग करें और प्रक्रियात्मक कोड में चयन करें। – dkretz

+0

धन्यवाद ले dorfier, जो सीमा के साथ मुद्दे हल करता है, मैं सुझाव के रूप में संपादित करेंगे। – Turnkey

+0

मैं कुछ ऐसा ही कर रहा हूं। मैंने यूनियन के परिणामस्वरूप "आईडी एएससी द्वारा ऑर्डर" जोड़ा, इसलिए पंक्तियां इरादे के रूप में वापस आईं। आपको आईडी डीईएससी द्वारा पहली ORDER को बदलने की आवश्यकता होगी, अन्यथा पहले कुछ पंक्तियां हमेशा वापस आ जाएंगी। –

0

यह मानक "पंक्ति क्रम" समस्या है ... यदि आपके डेटाबेस में पंक्ति है, तो आप इसका उपयोग कर सकते हैं, अन्यथा आपको एक सबक्वायरी की आवश्यकता है जो पंक्तियों के संख्या को वर्तमान पंक्ति की आईडी से कम आईडी के साथ गिना जाता है ... इस तरह:

- asssuming @Id "मध्यम"

Select * From Photos P 
Where (Select Count(*) From Photos 
     Where id <= P.Id) 
    Between (Select Count(*) From Photos 
       Where id < @Id) - 4 
     And (Select Count(*) From Photos 
       Where id < @Id) + 4 

के रूप में एक टिप्पणी एलबम मुद्दा आप प्रत्येक सबक्वेरी

Select * From Photos P 
    Where (Select Count(*) From Photos 
      Where album = @album 
      And id <= P.Id) 
    Between (Select Case When Count(*) < 4 
         Then 4 Else Count(*) End 
       From Photos 
       Where album = @album 
       And id < @Id) - 4 
     And (Select Case When Count(*) < 4 
         Then 4 Else Count(*) End 
       From Photos 
       Where album = @album 
        And id < @Id) + 4 
करने के लिए एल्बम विधेय जोड़ना चाहते हैं उठाया में आईडी का मूल्य है
+0

एल्बम द्वारा अतिरिक्त फ़िल्टर होना चाहिए, अन्यथा यह समस्या का समाधान नहीं करता है - यानी यह अनुक्रमिक आईडी पर ही काम करेगा। –

1

आप एसक्यूएल सर्वर का उपयोग कर रहे हैं, तो आप आप पंक्ति आदेश सूचकांक देने के लिए और इस तरह कुछ करने के लिए ROW_NUMBER() फ़ंक्शन का उपयोग कर सकते हैं:

declare @selected_photo integer; 
set @selected_photo = 5; 

declare @buffer_size integer; 
set @buffer_size = 2; 

select 
    ph.rownum, 
    ph.id 
from 
    (select row_number() over (order by Id) as rownum, * from Photos) as ph 
where 
    ph.rownum between case 
         when @selected_photo - @buffer_size < 1 then 1 
         else @selected_photo - @buffer_size 
         end 
         and @selected_photo + @buffer_size 

संपादित करें: यहाँ ROW_NUMBER अनुकरण पर एक लेख है() फ़ंक्शन MySQL में, के साथ संयोजन यह आपको जो चाहिए उसे प्राप्त कर सकता है - मैं इसे आज़माउंगा लेकिन मेरे पास काम पर खेलने के लिए एक MySQL डीबी आसान नहीं है।:-)

http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/

+0

धन्यवाद रॉन - लेकिन मैं MySQL का उपयोग कर रहा हूं, इसलिए मुझे नहीं लगता कि मैं इसका उपयोग कर सकता हूं - क्या मैं कर सकता हूं? –

+0

मुझे MySQL दस्तावेज़ों में कुछ भी समान नहीं दिख रहा है ... लेकिन मैं चारों ओर पोकिंग रखूंगा। :-) –

+0

@RonSavage: परेशान मत करो। MySQL कुछ डीबीएमएस में से एक है जो विंडोिंग फ़ंक्शंस का समर्थन नहीं करता है। –