2011-02-01 14 views
8

पर दिए गए खंड में अगली पंक्ति खोजें मेरे पास एक MySQL डेटाबेस में products नामक एक तालिका है। products इस तरह की कुछ क्या दिखता है:एसक्यूएल: एक आईडी

id name  din  strength active deleted 
1 APA TEST 00246374 25  1  0 
4 APA BOB 00246375 50  1  0 
5 APA TIRE 00246888 50  1  0 
7 APA ROT 00521414 100  1  0 
9 APA APA 01142124 100  1  0 
6 APA CODE 00121212 150  1  0 
8 APA SERV 00011145 600  1  0 

जाहिर है मैं कई स्तंभ बाहर छोड़ दिया है मेरे सवाल के लिए महत्वपूर्ण नहीं। जब मैं इस तालिका से पूछता हूं, तो मैं कई अलग-अलग कॉलमों में से एक द्वारा सॉर्ट करूँगा (उपयोगकर्ता इंटरफ़ेस अलग-अलग उपयोगकर्ताओं को सॉर्टिंग कॉलम और ऑर्डर बदलने की इजाजत देता है), और मेरे पास एक खोज खंड हो सकता है जिस स्थिति में मैं एक LIKE क्लॉज करूंगा नाम और डीआईएन।

मैं क्या जानना चाहता हूं, सॉर्टिंग जानकारी और खोज जानकारी, और एक विशिष्ट उत्पाद की आईडी (कहें मैंने 004 की खोज की, जो 3 परिणाम लौटा, और मैं उनमें से एक को देख रहा हूं), मैं कैसे कर सकता हूं अगले और पिछले उत्पादों को प्राप्त करें?

मैं यह करने की जरूरत है, क्योंकि एक उपयोगकर्ता खोज और परिणाम छँटाई के बाद उत्पादों को देखते हुए एक संपादित करने के लिए/क्लिक करता है तो वे पिछले पृष्ठ पर जाए बिना परिणामों से गुजरने के लिए सक्षम होना चाहता हूँ।

क्या एसक्यूएल में ऐसा करने का कोई अच्छा और कारगर तरीका है, या क्या मैं PHP का उपयोग करके सबसे अच्छा हूं? किसी भी विचार का भी स्वागत है।

वर्तमान में यह SQL क्वेरी का उपयोग कर, जो समस्या आ रही है, तो मैं इन सबसे strength कॉलम के आधार पर के रूप में वहाँ डुप्लिकेट मानों

SELECT T.* 
FROM `wp_products` T 
INNER JOIN `wp_products` curr on curr.id = 38 
    AND ((T.strength = curr.strength and T.id < curr.id) 
    OR (T.strength > curr.strength)) 
WHERE T.active = 1 AND T.deleted = 0 AND (T.name LIKE '%%' OR T.din LIKE '%%') 
ORDER BY T.strength ASC, T.id ASC 
LIMIT 1 

मेरे PHP कोड (वर्डप्रेस का उपयोग कर) (अगले आइटम प्राप्त करने के लिए बनाया गया है)

हैं
$sql = 'SELECT T.* 
FROM `' . $wpdb->prefix . 'apsi_products` T 
INNER JOIN `' . $wpdb->prefix . 'apsi_products` curr on curr.id = ' . $item->id . ' 
    AND ((T.' . $wpdb->escape($query['orderby']) . ' = curr.' . $wpdb->escape($query['orderby']) . ' and T.id > curr.id) 
    OR (T.' . $wpdb->escape($query['orderby']) . ' > curr.' . $wpdb->escape($query['orderby']) . ')) 
WHERE T.active = 1 AND T.deleted = 0 AND (T.name LIKE \'%' . $query['where'] . '%\' OR T.din LIKE \'%' . $query['where'] . '%\') 
ORDER BY T.' . $wpdb->escape($query['orderby']) . ' ' . $query['order'] . ', T.id ASC 
LIMIT 1;'; 

उत्तर

5

आपको वर्तमान रिकॉर्ड का संदर्भ होना चाहिए, और उसके बाद क्रमबद्ध कॉलम के आधार पर अगले रिकॉर्ड की प्रगतिशील रूप से देखें।

SELECT * 
FROM TABLE 
WHERE NAME LIKE '%X%' AND DIN LIKE '%%' 
ORDER BY Active, DIN, Name 
LIMIT 1; 

अगला:: नीचे उदाहरण मानता है उस पर

ORDER BY Active, DIN, NAME 

पहले सॉर्ट की गई है (सुनिश्चित करें कि आप अलग CURR.ID = 6 और उचित कोष्ठक के साथ और अन्य रैंकों-बनाने!)

SELECT * 
FROM TABLE T 
INNER JOIN TABLE CURR ON CURR.ID = 6 # the current ID being viewed 
    AND ((T.Active = Curr.Active AND T.DIN = Curr.DIN AND T.NAME > Curr.Name) 
    OR (T.Active = Curr.Active AND T.DIN > Curr.DIN) 
    OR T.Active > Curr.Active) 
WHERE T.NAME LIKE '%X%' AND T.DIN LIKE '%%' 
ORDER BY T.Active, T.DIN, T.Name 
LIMIT 1; 

से नीचे प्रस्तुत एक कामकाजी नमूना
create table products 
(ID int, SEED int, NAME varchar(20), DIN varchar(10), ACTIVE int, DELETED int); 
insert products values 
(1, 0, 'Product #1', '004812', 1, 0), 
(2, 0, 'Product #2', '004942', 0, 0), 
(3, 0, 'Product #3', '004966', 1, 0), 
(4, 0, 'Product #4', '007437', 1, 1), 
(5, 2, 'Product #2', '004944', 0, 0), 
(6, 2, 'Product #2', '004944', 1, 0); 

SELECT * 
FROM products 
WHERE active = 1 AND deleted = 0 
ORDER BY din DESC, ID desc; 

Output: 
"ID";"SEED";"NAME";"DIN";"ACTIVE";"DELETED" 
"3";"0";"Product #3";"004966";"1";"0" 
"6";"2";"Product #2";"004944";"1";"0" 
"1";"0";"Product #1";"004812";"1";"0" 

तो वर्तमान आईडी = 6 के साथ पंक्ति है, अगले रिकॉर्ड

SELECT T.* 
FROM products T 
INNER JOIN products curr on curr.ID = 6 
    AND ((T.din = curr.din and T.ID > curr.ID) 
    OR (T.din < curr.din)) 
WHERE T.active = 1 AND T.deleted = 0 
ORDER BY T.din DESC, T.ID ASC 
LIMIT 1; 
+0

क्षमा करें, मैं हमेशा SQL के साथ भयानक रहा हूं। क्या मुझे सीयूआरआर के संदर्भों को छोड़ देना चाहिए, या क्या मुझे अपने टेबल नामों में सीयूआरआर और टेबल बदलना चाहिए? –

+0

तालिका आपके तालिका के नाम के लिए प्लेसहोल्डर है। सीयूआरआर और टी उपनाम हैं - उन्हें अकेला छोड़ दें। – RichardTheKiwi

+0

मुझे आपकी क्वेरी के बिना सफलता नहीं मिल रही है, संभावना से अधिक मैं कुछ गलत कर रहा हूं। मेरी क्वेरी इस तरह दिखती है: 'चयन करें * table_name से जहां सक्रिय = 1 और हटाया गया = 0 डीआईईसीसी द्वारा आदेश दिया गया है और जब मैं आपकी क्वेरी चलाता हूं तो मुझे अपनी क्वेरी द्वारा पहली पंक्ति वापस मिलती है, भले ही मैं वापस लौटाई गई 5 वीं आईडी का उपयोग कर रहा हूं । मुझे 6 वें आईडी से आईडी 38 प्राप्त करना चाहिए। विचार? –

0

दिलचस्प सवाल। मुझे नहीं लगता कि आप इसे एक प्रश्न में कर सकते हैं, लेकिन आप इसे तीन से दूर खींच सकते हैं।

पहले प्रश्न का जवाब पंक्ति खींचती है। यह चाल उनके द्वारा क्रमबद्ध कॉलम के मान को पकड़ने के लिए होगी। आइए मान लें कि यह "सॉर्टेड कॉलम" है और मान "एम" है। आइए मान लें कि आपको मिली पंक्ति की आईडी 10.

आपकी दूसरी क्वेरी पहले की तरह ही होगी, लेकिन "शीर्ष 1" होगी और जहां खंड "... और सॉर्ट किया गया कॉलम> = ' एम 'और आईडी <> 10 "यह आपको अगली पंक्ति प्राप्त करता है। आप 10 पंक्तियों को वापस लौटना चाहते हैं और इसे खत्म करने से रोकने के लिए उन्हें पकड़ सकते हैं।

पिछला पाने के लिए, अपना ऑर्डरिंग अवरोही पर स्विच करें, और जहां आप जो खंड जोड़ते हैं वह है "... और सॉर्ट कॉलम < = 'एम' और आईडी <> 10"। यह आपको पिछली पंक्ति प्राप्त करता है। फिर, आपके उपयोगकर्ता के लिए 10 पंक्तियां अधिक उपयोगी हो सकती हैं।

उम्मीद है कि इससे मदद मिलती है।

+0

यह एक क्वेरी में किया जा सकता है का उपयोग कर प्राप्त किया जा सकता है। मेरा उत्तर देखें – RichardTheKiwi

+0

मैंने इसे जल्दी से करने की कोशिश की, मुझे विश्वास नहीं है कि यह काम कर सकता है। मान लें कि मैं नाम कॉलम से सॉर्ट कर रहा हूं। उदाहरण के लिए भाग 'name'> =' PRODUCT NAME # 3 'काम नहीं करता है –

+0

@cyberwiki: अच्छा। –

1

memcached जैसे दृढ़ता कैश परत के बिना, जहां आप परिणाम संग्रहीत कर सकते हैं और क्वेरी को पुन: जारी किए बिना प्राप्त कर सकते हैं, एक साधारण समाधान query cache को mysql में सक्षम कर सकता है। इस तरह, कैश अन्य querys से अवैध नहीं है, जब आप क्वेरी परिणाम खींच की लागत कम कर दी जाएगी

+0

इसे केवल एक प्रश्न का उपयोग करके कुशलतापूर्वक किया जा सकता है। मेरे उत्तर – RichardTheKiwi

+0

@cyberwiki देखें जो मैं प्रश्न से समझता हूं, यह एक भी प्रश्न समस्या नहीं है, क्योंकि वस्तुओं से विभिन्न पृष्ठों से अनुरोध किया जाएगा। आपकी क्वेरी अलग-अलग वस्तुओं के लिए क्वेरी करने का तरीका बताएगी, लेकिन प्रत्येक पृष्ठ अनुरोध के लिए फिर से मूल्यांकन किया जाएगा, क्या आप सहमत हैं? – Ass3mbler

+0

हां, लेकिन उचित अनुक्रमण के साथ, प्रत्येक सीमा 1 आवश्यक रूप से आवश्यक रूप से केवल 1 रिकॉर्ड पुनर्प्राप्त करती है। प्रत्येक SO पृष्ठ लोड कम से कम 10 आइटमों को डीबी से अनुरोध करता है, इसलिए राउंड ट्रिप एक मामूली चिंता होनी चाहिए। – RichardTheKiwi

1

प्रत्येक के लिए परिणाम दिखाया गया है, सेटअप अगले और पिछले के साथ लिंक फिर से जारी उपयुक्त आईडी है।

सॉर्ट ऑर्डर विवरण दृश्य से बदला नहीं जा सकता है।

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