2013-08-06 12 views
49

के साथ जुड़ें अनुसंधान के घंटों के ठीक बाद और अभी भी डीबी :: चयन का चयन करने के बाद मुझे यह प्रश्न पूछना है। क्योंकि मैं अपने कंप्यूटर को दूर करने वाला हूं;)।लैरवेल फ्लुएंट क्वेरी बिल्डर सबक्वायरी

मैं उपयोगकर्ता का अंतिम इनपुट (टाइमस्टैम्प पर आधार) प्राप्त करना चाहता हूं। मैं कच्चे एसक्यूएल

SELECT c.*, p.* 
FROM users c INNER JOIN 
(
    SELECT user_id, 
      MAX(created_at) MaxDate 
    FROM `catch-text` 
    GROUP BY user_id 
) MaxDates ON c.id = MaxDates.user_id INNER JOIN 
    `catch-text` p ON MaxDates.user_id = p.user_id 
    AND MaxDates.MaxDate = p.created_at 

मैं stackoverflow पर एक और पोस्ट here से इस क्वेरी मिल गया के साथ ऐसा कर सकते हैं।

मैंने लैरवेल में धाराप्रवाह क्वेरी निर्माता के साथ ऐसा करने की कोशिश की है, हालांकि कोई सफलता नहीं है।

मुझे पता पुस्तिका का कहना है कि आप यह कर सकते हैं:

DB::table('users') 
    ->join('contacts', function($join) 
    { 
     $join->on('users.id', '=', 'contacts.user_id')->orOn(...); 
    }) 
    ->get(); 

लेकिन वह ज्यादा मदद नहीं कर रहा है, क्योंकि मैं कैसे मैं एक सबक्वेरी वहाँ इस्तेमाल कर सकते हैं नहीं दिख रहा है? कोई भी जो मेरे दिन को उजागर कर सकता है?

उत्तर

105

ठीक है आप सभी के लिए ठीक उसी समस्या के लिए खोज में निराशा में पहुंचे। मुझे आशा है कि आपको यह जल्दी मिलेगा, मैंने किया; ओ।

इस तरह हल किया जाता है। जोओस्टके ने मुझे जिथब में बताया कि "शामिल होने वाला पहला तर्क तालिका (या डेटा) है जिसमें आप शामिल हो रहे हैं।" और वह सही था।

यहां कोड है। अलग-अलग टेबल और नाम लेकिन आपको सही विचार मिल जाएगा? यह टी

DB::table('users') 
     ->select('first_name', 'TotalCatches.*') 

     ->join(DB::raw('(SELECT user_id, COUNT(user_id) TotalCatch, 
       DATEDIFF(NOW(), MIN(created_at)) Days, 
       COUNT(user_id)/DATEDIFF(NOW(), MIN(created_at)) 
       CatchesPerDay FROM `catch-text` GROUP BY user_id) 
       TotalCatches'), 
     function($join) 
     { 
      $join->on('users.id', '=', 'TotalCatches.user_id'); 
     }) 
     ->orderBy('TotalCatches.CatchesPerDay', 'DESC') 
     ->get(); 
+3

में उप क्वेरी के साथ क्वेरी इस पैकेज माना जाता है प्रश्न बनाने के लिए एक PHP उपकरण सेट प्रदान करने के लिए, फिर भी हमें क्वेरी लिखना होगा और इसे 'selectRaw' कथन द्वारा इंजेक्ट करना होगा! क्या आपके पास क्वेरी स्ट्रिंग के बजाय क्वेरी पर धाराप्रवाह क्वेरी ऑब्जेक्ट पास करने के लिए कोई भाग्य है? – HPM

+0

यदि आपके पास उप-चयन में पैरामीटर है तो यह असंभव हो जाता है - उदाहरण के लिए @ ph4r05 उत्तर देखें, लेकिन मुझे यकीन नहीं है कि यह उन बदसूरत से SQL और addBinding से बचने के लिए सरलीकृत किया जा सकता है या नहीं – JustAMartin

6

मैं काफी संबंधित समस्या का समाधान के लिए देख रहा था: समूह में नवीनतम रिकॉर्ड जो एन के साथ एक विशिष्ट greatest-n-per-group की एक विशेषज्ञता है खोजने = 1.

समाधान समस्या आप शामिल यहां से निपट रहे हैं (यानी, एलोक्वेंट में क्वेरी कैसे बनाएं) इसलिए मैं इसे पोस्ट कर रहा हूं क्योंकि यह दूसरों के लिए सहायक हो सकता है। यह शक्तिशाली अलोकेंट धाराप्रवाह इंटरफ़ेस का उपयोग करके उप-क्वेरी निर्माण का एक क्लीनर तरीका प्रदर्शित करता है जिसमें एकाधिक शामिल कॉलम और where स्थिति शामिल हो जाती है।

मेरे उदाहरण में मैं watch_id द्वारा पहचाने गए प्रति समूह के नवीनतम DNS स्कैन परिणाम (तालिका scan_dns) लाने के लिए चाहता हूं। मैं उप-क्वेरी अलग से बनाते हैं।

एसक्यूएल मैं बोलने में निपुण उत्पन्न करना चाहते हैं:

SELECT * FROM `scan_dns` AS `s` 
INNER JOIN (
    SELECT x.watch_id, MAX(x.last_scan_at) as last_scan 
    FROM `scan_dns` AS `x` 
    WHERE `x`.`watch_id` IN (1,2,3,4,5,42) 
    GROUP BY `x`.`watch_id`) AS ss 
ON `s`.`watch_id` = `ss`.`watch_id` AND `s`.`last_scan_at` = `ss`.`last_scan` 

मैं निम्नलिखित तरीके से किया था:

// table name of the model 
$dnsTable = (new DnsResult())->getTable(); 

// groups to select in sub-query 
$ids = collect([1,2,3,4,5,42]); 

// sub-select to be joined on 
$subq = DnsResult::query() 
    ->select('x.watch_id') 
    ->selectRaw('MAX(x.last_scan_at) as last_scan') 
    ->from($dnsTable . ' AS x') 
    ->whereIn('x.watch_id', $ids) 
    ->groupBy('x.watch_id'); 
$qqSql = $subq->toSql(); // compiles to SQL 

// the main query 
$q = DnsResult::query() 
    ->from($dnsTable . ' AS s') 
    ->join(
     DB::raw('(' . $qqSql. ') AS ss'), 
     function(JoinClause $join) use ($subq) { 
      $join->on('s.watch_id', '=', 'ss.watch_id') 
       ->on('s.last_scan_at', '=', 'ss.last_scan') 
       ->addBinding($subq->getBindings()); 
       // bindings for sub-query WHERE added 
     }); 

$results = $q->get(); 
0

Laravel

$resortData = DB::table('resort') 
     ->leftJoin('country', 'resort.country', '=', 'country.id') 
     ->leftJoin('states', 'resort.state', '=', 'states.id') 
     ->leftJoin('city', 'resort.city', '=', 'city.id') 
     ->select('resort.*', 'country.name as country_name', 'states.name as state_name','city.name as city_name', DB::raw("(SELECT GROUP_CONCAT(amenities.name) from resort_amenities LEFT JOIN amenities on amenities.id= resort_amenities.amenities_id WHERE resort_amenities.resort_id=resort.id) as amenities_name"))->groupBy('resort.id') 
     ->orderBy('resort.id', 'DESC') 
     ->get(); 
संबंधित मुद्दे