ক্যোয়ারী নির্মাতা বা স্বতঃস্ফূর্তভাবে অতিরিক্ত শর্তাবলী সহ একটি যোগদান করুন


93

আমি লারাভেল কোয়েরি বিল্ডারের সাথে একটি JOIN ক্যোয়ারী ব্যবহার করে একটি শর্ত যুক্ত করার চেষ্টা করছি।

<?php

$results = DB::select('
       SELECT DISTINCT 
          *
          FROM 
             rooms 
                LEFT JOIN bookings  
                   ON rooms.id = bookings.room_type_id
                  AND (  bookings.arrival between ? and ?
                      OR bookings.departure between ? and ? )
          WHERE
                bookings.room_type_id IS NULL
          LIMIT 20',
    array('2012-05-01', '2012-05-10', '2012-05-01', '2012-05-10')
);

আমি জানি আমি কাঁচা এক্সপ্রেশন ব্যবহার করতে পারি তবে তারপরে এসকিউএল ইঞ্জেকশন পয়েন্ট থাকবে। আমি কোয়েরি বিল্ডারের সাথে নিম্নলিখিতগুলি চেষ্টা করেছি তবে উত্পন্ন উত্স (এবং স্পষ্টত, ক্যোয়ারী ফলাফল) আমার উদ্দেশ্যটি নয়:

$results = DB::table('rooms')
    ->distinct()
    ->leftJoin('bookings', function ($join) {
        $join->on('rooms.id', '=', 'bookings.room_type_id');
    })
    ->whereBetween('arrival', array('2012-05-01', '2012-05-10'))
    ->whereBetween('departure', array('2012-05-01', '2012-05-10'))
    ->where('bookings.room_type_id', '=', null)
    ->get();

এটি লারাভেলের উত্পন্ন উত্স:

select distinct * from `room_type_info`
    left join `bookings` 
on `room_type_info`.`id` = `bookings`.`room_type_id` 
where `arrival` between ? and ? 
    and `departure` between ? and ? 
    and `bookings`.`room_type_id` is null

যেমন আপনি দেখতে পাচ্ছেন, ক্যোয়ারী আউটপুটটির কাঠামো নেই (বিশেষত JOIN স্কোপের অধীনে)। জোনের অধীনে অতিরিক্ত শর্ত যুক্ত করা কি সম্ভব?

লারাভেলের ক্যোয়ারী বিল্ডার ব্যবহার করে আমি কীভাবে একই ক্যোয়ারীটি তৈরি করতে পারি (যদি সম্ভব হয়) তবে এলওলিউড ব্যবহার করা আরও ভাল, বা ডিবি :: এর সাথে থাকা উচিত?

উত্তর:


139
$results = DB::table('rooms')
                     ->distinct()
                     ->leftJoin('bookings', function($join)
                         {
                             $join->on('rooms.id', '=', 'bookings.room_type_id');
                             $join->on('arrival','>=',DB::raw("'2012-05-01'"));
                             $join->on('arrival','<=',DB::raw("'2012-05-10'"));
                             $join->on('departure','>=',DB::raw("'2012-05-01'"));
                             $join->on('departure','<=',DB::raw("'2012-05-10'"));
                         })
                     ->where('bookings.room_type_id', '=', NULL)
                     ->get();

পুরোপুরি নিশ্চিত নয় যে এর মধ্যবর্তী ধারাটি লারাভেল-এ যোগদানের সাথে যুক্ত করা যায় কিনা।

মন্তব্য:

  • DB::raw() লারাভেলকে উদ্ধৃতি পিছনে না রাখার নির্দেশ দেয়।
  • পদ্ধতি যোগদান করতে একটি অবসান ক্ষণস্থায়ী করে আপনি আরো যোগ করতে পারেন এটি অবস্থার যোগ দিতে, on()যোগ হবে ANDঅবস্থা এবং orOn()যোগ হবে ORশর্ত।

উত্তর করার জন্য ধন্যবাদ. দুর্ভাগ্যক্রমে, উত্পন্ন ক্যোয়ারীটি সামান্য আলাদা হওয়ায় এখন যোগদানের শর্তটি and arrival >= ? and arrival <= ? and departure >= ? and departure <= ?পরিবর্তিত হয়েছে AND ( r.arrival between ? and ? OR r.departure between ? and ? )(দয়া করে ORঅনুচ্ছেদটি লক্ষ্য করুন )। এটি এমন ফলাফলের জন্য অতিরিক্ত সারি যুক্ত করে যা সেখানে না থাকা উচিত। আমার ধারণা, কিউবি ব্যবহার করে যোগদানের ক্ষেত্রে সমস্ত ধরণের শর্ত তৈরি করা সম্ভব নয়।
Dede

4
আসলে আমি লক্ষ্য করেছি যে? ওএন ক্লজগুলিতে যুক্ত হয় না। ওএন-এ থাকা মানগুলি প্যারামিটারাইজড নয় এবং এসকিউএল ইঞ্জেকশন থেকে সুরক্ষিত নয়। আমি সমাধানটি বের করার চেষ্টা করে একটি প্রশ্ন পোস্ট করেছি ।
প্রগ্রেহামার

4
এটি এর মূল প্রশ্নের উত্তর দেয়নি যার একটি বা ধারা রয়েছে যা এই প্রতিক্রিয়াতে উপেক্ষা করা হয়েছিল।
আয়নোস্কো

নিখুঁত সমাধান. একটি মান ব্যবহার করার সময় কেবল ডিবি :: কাঁচা ব্যবহার মনে রাখবেন, অন্যথায় লারাভেল (কমপক্ষে 5.6.29 এ) ফিরে উদ্ধৃতি যুক্ত করুন এবং লক্ষ্যটি "ব্রেক" করুন।
অ্যাড্রিয়ান হার্নান্দেজ-লোপেজ

35

আপনি বাম জোড়ায় সেই বন্ধনীগুলি প্রতিলিপি করতে পারেন:

LEFT JOIN bookings  
               ON rooms.id = bookings.room_type_id
              AND (  bookings.arrival between ? and ?
                  OR bookings.departure between ? and ? )

হয়

->leftJoin('bookings', function($join){
    $join->on('rooms.id', '=', 'bookings.room_type_id');
    $join->on(DB::raw('(  bookings.arrival between ? and ? OR bookings.departure between ? and ? )'), DB::raw(''), DB::raw(''));
})

তারপরে আপনাকে এই এসও পোস্টে বর্ণিত "সেটবাইন্ডিংস" ব্যবহার করে পরে বাইন্ডিংগুলি সেট করতে হবে: মডেলটিতে ব্যবহৃত লারাভেলের কাঁচা ডিবি কোয়েরিতে প্যারামিটারগুলি কীভাবে আবদ্ধ করতে হবে?

এটি সুন্দর নয় তবে এটি কাজ করে।


32

আপনার যদি কিছু প্যারাম থাকে তবে আপনি এটি করতে পারেন।

    $results = DB::table('rooms')
    ->distinct()
    ->leftJoin('bookings', function($join) use ($param1, $param2)
    {
        $join->on('rooms.id', '=', 'bookings.room_type_id');
        $join->on('arrival','=',DB::raw("'".$param1."'"));
        $join->on('arrival','=',DB::raw("'".$param2."'"));

    })
    ->where('bookings.room_type_id', '=', NULL)
    ->get();

এবং তারপরে আপনার জিজ্ঞাসাটি ফিরিয়ে দিন

প্রত্যাবর্তন $ ফলাফল;


23

এর মতো বর্গ কোয়েরি নমুনা

LEFT JOIN bookings  
    ON rooms.id = bookings.room_type_id
    AND (bookings.arrival = ?
        OR bookings.departure = ?)

লারাভেল একাধিক শর্তের সাথে যোগ দিন

->leftJoin('bookings', function($join) use ($param1, $param2) {
    $join->on('rooms.id', '=', 'bookings.room_type_id');
    $join->on(function($query) use ($param1, $param2) {
        $query->on('bookings.arrival', '=', $param1);
        $query->orOn('departure', '=',$param2);
    });
})

11

আমি লারাভেল ৫.২ ব্যবহার করছি এবং আমরা বিভিন্ন বিকল্পের সাথে যোগ দিতে পারি, আপনি আপনার প্রয়োজন অনুসারে পরিবর্তন করতে পারেন।

Option 1:    
    DB::table('users')
            ->join('contacts', function ($join) {
                $join->on('users.id', '=', 'contacts.user_id')->orOn(...);//you add more joins here
            })// and you add more joins here
        ->get();

Option 2:
    $users = DB::table('users')
        ->join('contacts', 'users.id', '=', 'contacts.user_id')
        ->join('orders', 'users.id', '=', 'orders.user_id')// you may add more joins
        ->select('users.*', 'contacts.phone', 'orders.price')
        ->get();

option 3:
    $users = DB::table('users')
        ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
        ->leftJoin('...', '...', '...', '...')// you may add more joins
        ->get();

3

কাঁচা প্রশ্ন এবং মান নির্বাচন ( DB::rawএবং DB::selectপদ্ধতিগুলির মধ্যে) এর মধ্যে পার্থক্য রয়েছে ।

আপনি যা ব্যবহার করতে চান তা করতে পারেন DB::selectএবং ?প্রস্তুতির বিবৃতি (যেমন এটি আসলে যা করছে) ঠিক তেমন প্লেসহোল্ডারের মধ্যে ফেলে দেওয়ার মতো।

একটি ছোট উদাহরণ:

$results = DB::select('SELECT * FROM user WHERE username=?', ['jason']);

দ্বিতীয় প্যারামিটারটি মানগুলির একটি অ্যারে যা বাম থেকে ডানে কোয়েরিতে স্থানধারীদের প্রতিস্থাপন করতে ব্যবহৃত হবে।


এর অর্থ কি প্যারামিটারগুলি স্বয়ংক্রিয়ভাবে পালিয়ে গেছে (এসকিউএল ইঞ্জেকশন থেকে সংরক্ষণ করুন)?
Dede

4
হ্যাঁ, এটি PDO প্রস্তুত বিবৃতিগুলির জন্য কেবল একটি মোড়ক।
জেসন লুইস

বাম যোগে কোনও ওএন ক্লজে সেই কৌশলটি ব্যবহার করার কোনও উপায় আছে কি? আমার প্রশ্ন এখানে দেখুন । আমি আমার বাম জোইন ক্লোজারের ভিতরে চেষ্টা করার চেষ্টা $join->on('winners.year','=',DB::select('?',array('2013'));করেছি কিন্তু কাজ হয়নি।
প্রগ্রেহামার

এটি প্রকৃতপক্ষে স্পষ্টভাবে কাজ করার জন্য ডিজাইন করা হয়নি। আপনি পাশাপাশি কেবল একটি ডিবি :: কাঁচা () করতে পারেন এবং এটি নিজেই তৈরি করতে পারেন
mydoglixu
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.