2010-09-13 14 views
13
साथ

कल्पना कीजिए हम एक प्रश्न है: लाने के लिएएक तैयार बयान, 'कहां .. में (..) `क्वेरी और छँटाई - MySQL

SELECT * FROM somewhere WHERE `id` IN(1,5,18,25) ORDER BY `name`; 

और आईडी की एक सरणी: $ids = array(1,5,18,25)

के साथ तैयार बयान यह एक बयान तैयार करने और कई बार इसे कहते हैं adviced है:

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id`=?;'); 
foreach ($ids as $id){ 
    $stmt->bind_params('i', $id); 
    $stmt->exec(); 
    } 

लेकिन अब मैं मैन्युअल रूप से परिणामों को सॉर्ट करना होगा। क्या मेरे पास कोई अच्छा विकल्प है?

+0

लगता है कि बयानों की तैयारी के लिए तर्क अद्यतन करने की आवश्यकता थी जो एक प्रश्न में एकाधिक अपडेट का समर्थन नहीं करता है। जबकि आप चयन कर रहे हैं और इसलिए आपकी पहली क्वेरी पर्याप्त है। –

+0

मुझे विश्वास था कि ऐसे मामलों में तैयार बयान अच्छे नहीं हैं। एकमात्र अच्छा समाधान 'एक प्रश्न ऊपर जाना' है और यहां इस प्रकार की आईडी को सॉर्ट किया गया है, यहां नहीं। – kolypto

उत्तर

19

आप इसे इस तरह से कर सकता है:

$ids = array(1,5,18,25); 

// creates a string containing ?,?,? 
$clause = implode(',', array_fill(0, count($ids), '?')); 


$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $clause . ') ORDER BY `name`;'); 

call_user_func_array(array($stmt, 'bind_param'), $ids); 
$stmt->execute(); 

// loop through results 

इस आप प्रत्येक आईडी के लिए bind_param कॉल कर रहे हैं और आप क्रमित mysql के द्वारा किया जाता है का उपयोग करना।

+1

हाँ, लेकिन बुरी बात यह है कि क्वेरी का पुन: उपयोग नहीं किया जा सकता है इसलिए इसे तैयार करने की कोई आवश्यकता नहीं है :) – kolypto

+1

@o_O Tync: कम डेटाबेस यात्राएं, बेहतर। प्रीपेरस्टेटमेंट बाधाओं के साथ चिपकने के लिए आपका स्वागत है, लेकिन यदि आपको उसी तालिका में 10/20/50/100/1000 + क्वेरी चलाने की आवश्यकता है तो यह स्केल नहीं होगा। –

+1

क्या इस कथन के लिए सिर्फ एक दृश्य बनाने के लिए बेहतर नहीं होगा क्योंकि इसे किसी भी तरह से पुन: उपयोग नहीं किया जा सकता है? –

0

नहीं, यदि आप ORDER BY खंड का उपयोग कर डेटाबेस से कुछ रिकॉर्ड प्राप्त करना चाहते हैं, तो इसकी अनुशंसा नहीं की जाती है।

1

परिणाम ऑब्जेक्ट पर PHP usort फ़ंक्शन का उपयोग करने का एक विकल्प होगा, लेकिन यह "मैन्युअल" है।

इस देखें: Sort Object in PHP

3

मैं एक अंत में धीमी गति से & बदसूरत समाधान जो फिर भी सरणी आइटम के किसी भी संख्या के लिए तैयार बयान का उपयोग करता है :) 3 बयान किसी भी मामले के लिए सार्वभौमिक हैं और हर जगह उपयोग किया जा सकता जोड़ देंगे।

  1. CREATE TEMPORARY TABLE आईडी ( आईडी INT);
  2. INSERT INTO आईडी VALUES(?); इस अपनी आईडी अन्य तालिकाओं से LEFT JOIN .... ; डेटा उपयोग ids सूची
  3. SELECT आईडी FROM आईडी ; सब कुछ का चयन सॉर्ट करने के लिए जोड़ दिया जाएगा
  4. SELECT आईडी FROM आईडी पीछे

अन्यथा आपको IN (?,?,?,.... का उपयोग करना होगा या पंक्तियों को मैन्युअल रूप से सॉर्ट करना होगा। सबसे अच्छा विचार सरल MySQL-querys का उपयोग करना है, या, जिस तरह से आप पसंद करते हैं पहले से क्रमबद्ध आईडी की सूची प्राप्त करने का प्रयास करें।

0

क्या आपने एक जॉइन और WHERE क्लॉज का उपयोग करके मूल क्वेरी को फिर से लिखने पर विचार किया है, जिसमें आईडीएस प्राप्त करने के लिए आपको आवश्यकता है, जहां आपको खंड में किसी आवश्यकता की आवश्यकता से बचने की आवश्यकता है? मैं यहां एक ही प्रश्न के साथ आया था और संभावित समाधानों की समीक्षा करने के बाद मुझे एहसास हुआ कि एक इंटर्न जॉइन मेरा समाधान था।

+0

वह आंतरिक तर्क था: ऐप को एन द्वारा उपयोगकर्ताओं को बाहरी रूप से प्रदान करने के लिए आवश्यक था। खुशी है कि आपका मामला इतना विशिष्ट नहीं हुआ :) – kolypto

5

मेरा मानना ​​है कि यह सरल संभव जवाब है:

$ids = [1,2,3,4,5]; 
$pdos = $pdo->prepare("SELECT * FROM somwhere WHERE id IN (:" 
     . implode(',:', array_keys($ids)) . ") ORDER BY id"); 

foreach ($ids as $k => $id) { 
    $pdos->bindValue(":". $k, $id); 
} 

$pdos->execute(); 
$results = $pdos->fetchAll(); 

इतने लंबे समय के आईडी की अपनी सरणी अवैध पात्रों के साथ कुंजी या कुंजियों शामिल नहीं है, यह काम wil।

1

एक ही समस्या थी और 7 साल पहले @sled के जवाब के अलावा, यहां call_user_func_array(array($stmt, 'bind_param'), $ids); कदम बनाने के बिना एक संभावना है, लेकिन केवल एक बार bind_params फोन: लिंक आप मेरे द्वारा प्रदान के अनुसार

$ids = array(1,5,18,25); 

// creates a string containing ?,?,? 
$bindClause = implode(',', array_fill(0, count($ids), '?')); 
//create a string for the bind param just containing the right amount of iii 
$bindString = str_repeat('i', count($ids)); 

$stmt = $mysqli->prepare('SELECT * FROM somewhere WHERE `id` IN (' . $bindClause . ') ORDER BY `name`;'); 

$stmt->bind_params($bindString, ...$ids); 
$stmt->execute(); 
संबंधित मुद्दे