PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label laravel-query-builder. Show all posts
Showing posts with label laravel-query-builder. Show all posts

Tuesday, November 15, 2022

[FIXED] How to add model's relationed condition to Eloquent query in Laravel 6.x?

 November 15, 2022     eloquent, laravel, laravel-6, laravel-query-builder, php     No comments   

Issue

In my Laravel 6.x project I have Product model, ProductCategory and WarehouseProduct models.

In the Product I store the base information of my products. In ProductCategory model I store the category informations of products. In the WarehouseProduct I store the stock amount informations about products in warehouse. Of course I have many warehouses with many products.

My Product looks like this:

class Product extends Model
{
    protected $fillable = [
        'name',
        'item_number',
        // ...
    ];

    public function categories() {
        return $this->belongsToMany(ProductCategory::class, 'product_category_products',
            'product_id', 'product_category_id');
    }
}

The ProductCategory looks like this:

class ProductCategory extends Model
{
    protected $fillable = [
        'name',
        'description',
        // ...
    ];


    public function products() {
        return $this->belongsToMany(Product::class, 'product_category_products',
            'product_category_id', 'product_id');
    }
}

The WarehouseProduct looks like this:

class WarehouseProduct extends Model
{
    protected $fillable = [
        'product_id',
        'warehouse_id',
        'amount',
        // ...
    ];

    public function product() {
        return $this->belongsTo(Product::class, 'product_id');
    }
}

I have this query now:

$query = WarehouseProduct::select([
    'product_id',
    'warehouse_id',
    DB::raw('SUM(free_amount)'),
    DB::raw('SUM(booked_amount)'),
    // ...
]);

if (isset($request->warehouse_id)) {
    $query->where([['warehouse_id', '=', $request->warehouse_id]]);
}

if (isset($request->product_category_id)) {
    // ???
}

How can I add a where condition to the query what said: products from this category?


Solution

You can query the Relationship Existence. As it is a relationship through another model (Product) you could reduce the query if you defined that Has Many Through relationship, but I think that this will be enough for this particular query.

$warehouse_id = $request->warehouse_id;
$product_category_id = $request->product_category_id;

$query = WarehouseProduct::select([
    'product_id',
    'warehouse_id',
    DB::raw('SUM(free_amount)'),
    DB::raw('SUM(booked_amount)'),
    // ...
])
->when($warehouse_id, function ($query) use ($warehouse_id) {
    $query->where('warehouse_id', $warehouse_id);
})
->when($product_category_id, function ($query) use ($product_category_id) {
    $query->whereHas('product', function ($que) use ($product_category_id) {
        $que->whereHas('categories', function ($q) use ($product_category_id) {
            $q->where('id', $product_category_id);
        })
    })
});

$results = $query->get();

Note that I am using the when method for the conditional clauses, but you can continue with the ifs as you was doing.



Answered By - porloscerros Ψ
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to make custom orderBy or DB::raw(FIELD()) with LIKE keyword and passing variable in laravel query builder

 November 15, 2022     laravel, laravel-6, laravel-query-builder, mysql     No comments   

Issue

I have a very simple solution but I dislike that. So, How can I do?

my data base is

--------------------------------------
id   name   view       created_at
--------------------------------------
1   one     9      2021-01-13 12:34:22
2   two     8      2021-01-15 10:23:02
3   three   23     2021-01-15 20:55:17
4   forth   15     2021-01-16 12:34:22
5   fifth   0      2021-01-19 10:37:02

I want to sort and get my data like this--

--------------------------------------
id   name   view       created_at
--------------------------------------
5   fifth   0      2021-01-19 10:37:02
3   three   23     2021-01-15 20:55:17
4   forth   15     2021-01-16 12:34:22
1   one     9     2021-01-13 12:34:22
2   two     8     2021-01-15 10:23:02

My solution is

        $today = '2021-01-19';  //this date will calculate in daily. Not absolute date!

        $firstarray=Product::where('created_at','LIKE',$today.'%')->get();
        $secondarray=Product::orderBy('viewer', 'DESC')->get();
        $data = array_merge($firstarray,$secondarray);
        return $data;

In real, I want to make my code like this

    $today = '2021-01-19';  //this date will calculate in daily. Not absolute date!
    $data = Product::orderBy(DB::raw('FIELD(created_at, LIKE $today."%")'),'DESC')
            ->orderBy('view','desc')->get();
    return $data;

How can I get powerful code for my problem?

Sorry for my english skill
thank all


Solution

Your question is not clear! If it's the way I understand, that's the solution.

$data = Product::whereDate('created_at', now())->orderBy('view','desc')->get();


Answered By - Yunus Kocabay
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, August 1, 2022

[FIXED] How can i paginate laravel collection?

 August 01, 2022     laravel, laravel-collection, laravel-query-builder, model-view-controller, pagination     No comments   

Issue

here is how i trying to paginate:

$posts = Post::all()->sortByDesc("created_at")->pagination(1);

but i get this error:

Method Illuminate\Database\Eloquent\Collection::pagination does not exist.


Solution

It is because paginate is Builder method, not collection.

You need to create paginator manually, how described here - https://laravel.com/docs/8.x/pagination#manually-creating-a-paginator



Answered By - Anton
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, April 19, 2022

[FIXED] How can fetching huge records using Laravel and MySQL?

 April 19, 2022     laravel, laravel-5, laravel-eloquent, laravel-query-builder, mysql     No comments   

Issue

I Need experts Suggestions and Solutions. We are developing job portal website here by handle around 1 million records. We are facing records fetching timeout errors. How can I handle those records using laravel and MySql?

We are trying to follow steps:

  1. Increase the PHP execution time
  2. MySql Indexing
  3. Paginations

Solution

You should be chunking results when working with large data sets. This allows you to process smaller loads, reduces memory consumption and allows you to return data to the User while the rest is being fetched/processing. See the laravel documentation on chunking:

https://laravel.com/docs/5.5/eloquent#chunking-results

To further speed things up you can leverage multithreading and spawn concurrent processes that each handle a chunk at a time. Symfony's Symfony\Component\Process\Process class makes this easy to do.

https://symfony.com/doc/current/components/process.html



Answered By - user320487
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to select every nth row in Laravel query builder

 April 19, 2022     laravel, laravel-query-builder, mysql, reactjs     No comments   

Issue

I have an API that fetches data using Laravel query builder. I make a call to this API from a react app. I have a new row every 5 minutes in my database and I need to be able to retrieve the data for a day or for a period (like a week or two). Making this call makes my react app very slow, even when I only fetch the data for a single day. I need to be able to select every nth row which would improve performance (as well as the readability of the chart I create based on the data...).

Instead of retrieving every record (every 5 minutes) I want to be able to retrieve 1 every 12 for example (every 60 minutes)

The time (log_time in my DB) is stored in a weird way: 103500 being 10:35 AM. In want to use a modulo in my query but I cannot make it work...

$data = DB::connection('mysql')->table('my_table')
    ->select('value','log_date','log_time')
    ->where('id_user',$userId)
    ->where('log_time', mod 500 = 0)    // This is the line I cannot get to work
    ->orderBy('log_date')
    ->orderBy('log_time')->get();

I tried different things for that line. Some were desperate attempts...

->where('log_time', mod 500 = 0)   // unexpected '500', expecting ')' 
->where('log_time mod 500 = 0')    // Unknown column 'log_time mod 500 = 0'
->where('log_time mod 500', 0)     // Unknown column 'log_time mod 500'
->where('log_time', % 500 = 0)     // unexpected '%', expecting ')' 
->where('log_time % 500 = 0')      // Unknown column 'log_time % 500 = 0'
->where('log_time % 500', 0)       // Unknown column 'log_time % 500'
->where('log_time', mod 500, 0)    // unexpected '500', expecting ')' 
->where('log_time', 'mod 500', 0)  // only return result for 'log_time' = 0 (midnight)
->where('log_time', % 500, 0)      // unexpected '500', expecting ')'
->where('log_time', '% 500', 0)    // only return result for 'log_time' = 0 (midnight)
->where('log_time', MOD(500,0))    // Call to undefined function MOD()

I also tried with ->whereRaw which didn't work either.


Solution

I cannot try it out at the moment but maybe a whereRaw could help?

->whereRaw('log_time MOD 500 = 0')



Answered By - Aless55
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to resolve ambiguous error in the query

 April 19, 2022     join, laravel, laravel-query-builder, mysql, sql     No comments   

Issue

I am using laravel framework for developing API's ,i have one query that is executed without where condition without any error i need to execute with where condition but it's throwing an error

query

select count(*) as aggregate
from `users`
  left join `books` on `books`.`book_id` = `books`.`id`
where `access_id` = 5054

SQL Error [1052] [23000]: Column 'access_id' in where clause is ambiguous

after searching google i got something we have to specify reference of a table name , i added reference name like this where users.access_id =5054 but it's throwing an error like unknown column but in my db i have that column in both users and books table


Solution

The problem is its consider as a column so that's why syntax error is coming,try following way it will resolve your problem

select count(*) as aggregate
from `users`
  left join `books` on `books`.`book_id` = `books`.`id`
where `users`.`access_id` = 5054



Answered By - Sai Tarun
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, April 18, 2022

[FIXED] How to convert rows into columns in laravel

 April 18, 2022     eloquent, laravel, laravel-query-builder, mysql, pivot     No comments   

Issue

I am totally new in web developing... What I want is this:

row records converted into columns in Excel

The records that i get have three main columns, 'DateTime', 'meter_type', 'value'... Now in here, meter_type have same values i.e. like from 1 to 8 (in image, it is 72 to 79) for different values of DateTime and value... As an example, at DateTime: 2016-06-23 00:01:00, i get 8 different values for all 8 different meter types and similarly at DateTime: 2016-06-23 00:02:00, i will get new set of 8 values for all meter_types...

Now what I want is, to group 'DateTime' column for different 'meter_type' i.e., in this case (above example), I want 9 columns (in total), 1 column for DateTime and remaining all 8 columns depicting 8 meter_type and records for these columns will be value of them... Please refer image for more clarification...

And I want to do this in travel using query builders or eloquent... I googled this, but I didn't found anything useful in travel for what I want... Please help me out here... documentations or properly detailed examples for achieving what I want will really be appreciated.


Solution

Look like a perfect use for the group by method on collections:

https://laravel.com/docs/master/collections#method-groupby

That way if you do

$collection->groupBy('meter_type');

You'll have an array using the meter type as key and all records regarding that meter type in each.



Answered By - Atrakeur
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, March 8, 2022

[FIXED] Laravel eloquent with() nested relationship fields in parent unnested

 March 08, 2022     eloquent, eloquent-relationship, laravel, laravel-query-builder, laravel-relations     No comments   

Issue

the elequent query i have is:

$rows = ProjectLogin::with(
    'User:PRIVATE,naam', 
    'Project:PRIVATE,naam', 
    'Queue:PRIVATE,queue_naam', 
    'AgentStatus:PRIVATE,status'
)
->limit(10)->get();

this will return this array if i do $rows->toArray():

array:10 [▼
  0 => array:18 [▶]
  1 => array:18 [▼
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => "PRIVATE"
    "PRIVATE" => "PRIVATE"
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "user" => array:2 [▼
      "PRIVATE" => PRIVATE
      "naam" => "SOME NAME"
    ]
    "project" => array:2 [▼
      "PRIVATE" => PRIVATE
      "naam" => "SOME PROJECT NAME"
    ]
    "queue" => null
    "agent_status" => array:2 [▼
      "PRIVATE" => PRIVATE
      "status" => "SOME STATUS"
    ]
  ]
  2 => array:18 [▶]
  3 => array:18 [▶]
  4 => array:18 [▶]
  5 => array:18 [▶]
  6 => array:18 [▶]
  7 => array:18 [▶]
  8 => array:18 [▶]
  9 => array:18 [▶]
]

the withs are in a array, but i dont want nested arrays, plus it contains the foreign keys which i dont need.

i want the array to look like for example:

array:10 [▼
  0 => array:18 [▶]
  1 => array:18 [▼
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => "PRIVATE"
    "PRIVATE" => "PRIVATE"
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "PRIVATE" => PRIVATE
    "user_naam" => 'SOME NAME'
    "project_naam" => 'SOME NAME'
    "agent_status_status" => 'SOME STATUS'
    
  ]
  2 => array:18 [▶]
  3 => array:18 [▶]
  4 => array:18 [▶]
  5 => array:18 [▶]
  6 => array:18 [▶]
  7 => array:18 [▶]
  8 => array:18 [▶]
  9 => array:18 [▶]
]

How can i get specifics columns from a query that uses with() in the main array instead of nested arrays?


Solution

i found 2 solutions to my issue.

the first solution is accepting relations are nested and making sure they return default fields with the "withDefault()" method. which would look like:

$rows = ProjectLogin::
with([
    'User' => function($query) { 
        $query->select('PRIVATE','naam')
        ->withDefault(['PRIVATE' => '','naam' => '']); 
    },
    'Project' => function($query) { 
        $query->select('PRIVATE','naam')
        ->withDefault(['PRIVATE' => '','naam' => '']); 
    },
    'Queue' => function($query) { 
        $query->select('PRIVATE','queue_naam')
        ->withDefault(['PRIVATE' => '','queue_naam' => '']); 
    },
    'AgentStatus' => function($query) { 
        $query->select('PRIVATE','status','status_colour')
        ->withDefault(['PRIVATE' => '','status' => '','status_colour' => '']); 
    },
]
)->get();

the other solution is if nested array are not a option is using "map()" which would look like:

$rows = ProjectLogin::with(
    'User:PRIVATE,naam', 
    'Project:PRIVATE,naam', 
    'Queue:PRIVATE,queue_naam', 
    'AgentStatus:PRIVATE,status,status_colour'
)
->get()
        ->map(function($item) {
            $item = $item->toArray();
            return [
            'PRIVATE' => $item['PRIVATE'],
            'PRIVATE' => $item['PRIVATE'],
            'PRIVATE' => $item['PRIVATE'],
            'PRIVATE' => $item['PRIVATE'],
            'user_name' => @$item['user']['naam'],
            'project_name' => @$item['project']['naam'],
            'queue_name' => @$item['queue']['queue_naam'],
            'status' => @$item['agent_status']['status'],
            'PRIVATE' => $item['PRIVATE'],
            'status_colour' => @$item['agent_status']['status_colour'],
            ];
        });

the $item = $item->toArray(); is important, otherwise it will create new queries that make n+1 obsolete.



Answered By - fidderr
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, March 4, 2022

[FIXED] Convert mysql query to working with laravel

 March 04, 2022     eloquent, laravel-5, laravel-query-builder, mysql     No comments   

Issue

I have this MySQL query which is working fine for me. Now I decided to convert my project to Laravel project so I want to convert the MySQL query to a Laravel query.

This is my query:

select c.username,
    max(case when c.attribute = 'Cleartext-Password' then c.value end) as password,
    max(case when c.attribute = 'Expiration' then c.value end) as expiration,
    max(case when c.attribute = 'ChilliSpot-Max-Total-Octets' then c.value end) as quta,
    max(case when c.attribute = 'Simultaneous-Use' then c.value end) as simul,
    max(case when c.attribute = 'Max-All-Session' then c.value end) as session,
    max(c.adsoyad) as realname, min(c.dtarih) as birthdate, min(c.telefon) as phone,min(c.tcno) as tc,max(c.email) as email,min(c.id) as id
from radcheck c 
group by c.username

How can I do it?


Solution

To convert above using laravel query builder you need to go for raw expressions

$result = DB::table('radcheck as c')
    ->select('c.username', 
    DB::raw("max(case when c.attribute = 'Cleartext-Password' then c.value end) as password"),
    DB::raw("max(case when c.attribute = 'Expiration' then c.value end) as expiration"),
    DB::raw("max(case when c.attribute = 'ChilliSpot-Max-Total-Octets' then c.value end) as quta"),
    DB::raw("max(case when c.attribute = 'Simultaneous-Use' then c.value end) as simul"),
    DB::raw("max(case when c.attribute = 'Max-All-Session' then c.value end) as session"),
    DB::raw("max(c.adsoyad) as realname"),
    DB::raw("min(c.dtarih) as birthdate"),
    DB::raw("min(c.telefon) as phone"),
    DB::raw("min(c.tcno) as tc"),
    DB::raw("max(c.email) as email"),
    DB::raw("min(c.id) as id")
    )
    ->groupBy('c.username')
    ->get();


Answered By - M Khalid Junaid
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, February 28, 2022

[FIXED] Laravel Concat to get first name + middle name + last name

 February 28, 2022     datatables, laravel, laravel-query-builder, php     No comments   

Issue

I'm trying to achieve a search on datatable. Right now, I'm only able to search for first name, middle name and last name etc. However, when searching for the full name (first middle and last name) the search won't work. image: success search for firtname/middle/last image2: not working when searching for fullname

In my controller, I'm using the DB::raw() concat inside a function. Here's my code:

$query->Where(function($query) use ($s)
    {
    $query->Where(DB::raw("CONCAT('first_name', ' ', 'middle_name')"), 'like', '%'.$s.'%')
    ->orwhere('first_name', 'ilike', '%'.$s.'%')
    ->orWhere('middle_name', 'ilike', '%'.$s.'%')
    ->orWhere('last_name', 'ilike', '%'.$s.'%')
    ->orWhere('email', 'ilike', '%'.$s.'%')
    ->orWhere('cellphone', 'ilike', '%'.$s.'%');
    });

Please share any fix or insights on this. Thank you in advance.


Solution

User::where(function($query) use ($input) {
            $query->orWhere(DB::raw('CONCAT(first_name, " ", middle_name," ",last_name)'), 'LIKE', '%' . $input['search'] . '%')
                    ->orWhere('first_name', 'LIKE', "%{$input['search']}%")
                    ->orWhere('middle_name', 'LIKE', "%{$input['search']}%")
                    ->orWhere('middle_name', 'LIKE', "%{$input['search']}%")
                    ->orWhere('last_name', 'LIKE', "%{$input['search']}%")
                    ->orWhere('email', 'LIKE', "%{$input['search']}%")
                    ->orWhere('cellphone', 'LIKE', "%{$input['search']}%");
        });

I hope it would work for you.



Answered By - Ankita Dobariya
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, February 21, 2022

[FIXED] Laravel Query Builder - Use sum method on a generated attribute

 February 21, 2022     eloquent, laravel, laravel-query-builder, mysql, php     No comments   

Issue

Let's say I have these 2 models:

Order Model:

  • id
  • state (incomplete, complete)

Item Model:

  • id
  • order_id
  • type
  • is_worthy.

.

/**
 * Returns the item's price according to its worthy
 */
public function getPriceAttribute()
{
    return $this->is_worthy ? 100 : 10; // $
}

So far so good.

Now I want to summarize the price of the complete orders. So I'm doing this:

App\Item::whereHas('order', function ($query) {
    $query->where('state', 'complete');
})->sum('price')

But the thing is, that I don't have in my items table the column price. Because the price attribute is generated in the Model.

So my question is, how can I summarize price of the complete orders?


Solution

There are 2 ways to do this:

1. Have PHP do all the work

$items = App\Item::whereHas('order', function ($query) {
    $query->where('state', 'complete');
})->get();
$sum = $items->sum(function($item) {
    return $item->price;
});
// In Laravel 5.4, you can replace the last line with $sum = $items->sum->price;

2. Have SQL do all the work

$items = App\Item::whereHas('order', function ($query) {
    $query->where('state', 'complete');
})->select('*', DB::raw('IF(is_worthy, 100, 10) as price'))->sum('price');


Answered By - Paras
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, February 12, 2022

[FIXED] Laravel: Merge two query builders

 February 12, 2022     laravel, laravel-query-builder     No comments   

Issue

I have a table of courses which will be free to access or an admin will need to click something to let users see the course.

The course table looks like this:

| id | title          | invite_only | 
|----|----------------|-------------|
| 1  | free course    | 0           |
| 2  | private course | 1           |

Separate from this I have a course_user table, where initially users request access, then admins can approve or deny access:

| id | user_id | course_id | approved | declined |
|----|---------|-----------|----------|----------|
| 1  | 3       | 2         | 1        | 0        |
| 2  | 4       | 1         | 0        | 1        |
| 3  | 4       | 2         | 0        | 0        |

I'd like to index all the courses a user has access to:

class User extends model{
  public function myCourses(){
    $public = $this->publicCourses;
    $invited = $this->invitedCourses;
    return $public->merge($invited);
  }
  public function publicCourses(){
    return $this
      ->hasMany('App\Course')
      ->where('invite_only', false);
  }
  public function invitedCourses(){
    return $this
      ->belongsToMany("\App\Course")
      ->using('App\CourseUser')
      ->wherePivot('approved', 1);
  }
}

How can I make the myCourses function return the results of both publicCourses and invitedCourses by doing only one database query? I'd like to merge the two query builder instances.


Solution

I was able to make a much simpler query, and use Laravel's orWherePivot to extract the correct courses:

public function enrolledCourses()
{
    return $this
      ->courses()
      ->where('invitation_only', false)
      ->orWherePivot('approved', true);
}


Answered By - Djave
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, February 4, 2022

[FIXED] Laravel order by price with condition special price

 February 04, 2022     eloquent, laravel, laravel-query-builder, mysql, php     No comments   

Issue

I have table with next columns (price, special_price, is_special).

+-------+------+-----------------+--------------+---------+
| id    | price |  special_price  | is_special   | qty      |
+-------+-------------------------+--------------+----------+
| 1     | 100   |    null         | 0            |  5       |
| 2     | 120   |    99           | 1            |  0       |
| 3     | 300   |    null         | 0            |  1       |
| 4     | 400   |    350          | 1            |  10      |
| 5     | 75    |    69           | 1            |  0       |
| 6     | 145   |    135          | 0            |  1       |
+-------+-------+-----------------+--------------+---------+

I want to get products ordered by 'price' with condition, if 'is_special' column is true then select 'special_price' column.

I want to get next result.

+-------+-----------+-----------------+--------------+--------------+
| id    | price     |  special_price  | is_special   | qty          |
+-------+-----------------------------+--------------+--------------+
| 5     | 75        |    69           | 1            |  0           |
| 2     | 120       |    99           | 1            |  0           |
| 1     | 100       |    null         | 0            |  5           |
| 6     | 145       |    135          | 0            |  1           |
| 3     | 300       |    null         | 0            |  1           |
| 4     | 400       |    350          | 1            |  10          |
+-------+-----------+-----------------+--------------+--------------+

On raw SQL it's looks like

SELECT *
FROM products
ORDER BY IF(is_special=0, price, special_price ) ASC;

I using Laravel and want to ordered and get query builder in result.

For example I did it with virtual attributes

/**
 * Get current price
 *
 * @return mixed
 */
 public function getCurrentPriceAttribute()
 {
     return $this->is_special ? $this->special_price : $this->price;
 }

And sorted collection $products->sortBy('current_price') but in this time I want to get query builder in result. Query builder not working with virtual attributes.

I'm trying to multiple sorting by two columns 'price' and 'qty'

$query = Product::query();

$query->orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC'));
$query->orderBy('qty', request('qty', 'DESC'));

$query->get();

I have 2 filter 'Quantity' and 'Price'.

In this multiple ordering I want to get products ordering by price, then all products ordering by 'qty'. Products with qty == 0, need to be next after all products with qty > 0.

Help me, please.


Solution

The First Problem

Query-Builder has no accessors, you need to select it out:

DB::table('products')
   ->select('*')
   ->addSelect(DB::raw('IF(is_special=0, price, special_price ) AS current_price'))
   ->orderBy('current_price')
   ->get();

PS:Recommend to sort in database, think about if you have paginate on products, it will sort only on the one page's datas when it return that page.


The second problem:

  1. qty > 0 AS 1, and qty = 0 AS 0, then order them DESC:

  2. Order by price with request

  3. Order by qty with request

So the products will put the qty > 0 before qty = 0, and the records that qty > 0 will ordering by price, then all products ordering by qty; and the records that qty = 0 will ordering by price, then all products ordering by qty too:

$query = Product::query();
$query->orderBy(DB::raw(IF('qty > 0, 1, 0')), 'DESC');
$query->orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'));
$query->orderBy('qty', request('qty', 'DESC'));
$query->get();

PS: orderByRaw("if(is_special=0, price, special_price) " . request('price', 'ASC') will be attack easily by SQL-Injection. Change to orderBy(DB::raw("IF(is_special=0, price, special_price)"), request('price', 'ASC'))



Answered By - TsaiKoga
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, February 1, 2022

[FIXED] How to get maximum amount and all other amounts separately in laravel?

 February 01, 2022     eloquent, laravel, laravel-5, laravel-query-builder     No comments   

Issue

Hello I am building an auction system. where for now i will consider two tables. Auction table and Bidding table. I want to build eloquent query so that I can get maximum amount and all other amounts separately because I will transfer maximum amount to seller and other amount to refund their users.

I don't know from where I should start.

Auction table migration

   public function up()
    {
        Schema::create('auctions', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->Integer('productID');
            $table->Integer('price');
            $table->Integer('quantity');
            $table->dateTime('endTimeDate');
            $table->dateTime('startTimeDate');
            $table->timestamps();
        });
    }

Bidding table migration

  public function up()
    {
        Schema::create('biddings', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->Integer('userID');
            $table->integer('auctionID');
            $table->bigInteger('amount');
            $table->timestamps();
        });
    }

I want to get maximum amount and other amounts separately.


Solution

Since the amount is just an integer, retrieve all amounts and pop the maximum out of the collection

$other_amounts = \DB::table('biddings')->select('amount')->orderBy('amount')->get();
$maximum = $other_amounts->pop(); // this will get the maximum
echo $other_amounts; // Here are all the amounts except the maximum


Answered By - Salim Djerbouh
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, January 26, 2022

[FIXED] How to count revisited customer ( more than 1 time) in laravel using query builder?

 January 26, 2022     laravel, laravel-5, laravel-query-builder, mysql     No comments   

Issue

I need to count revisited customer in one month. It means need to count customer_id has more than one entry in table within a month.

My query is showing only the total customer.

$count_customer_current_month = DB::table("customer_entry")->whereRaw('MONTH(date) = ?', 
                                [$currentMonth])->count();

Solution

Just use group by customer_id having COUNT(customer_id) > 1

$entry_customers = DB::table("customer_entry")
   ->whereRaw('MONTH(date) = ?', [$currentMonth])
   ->groupBy('customer_id')
   ->havingRaw("COUNT(customer_id) > 1")
   ->selectRaw('COUNT(customer_id) AS entry_count, customer_id');

If you want to get how many this customers:

$entry_customers->get()->count() // count the collections.

Or use subquery to get the customers count:

DB::table(DB::raw("({$entry_customers->getSql()}) AS entry_customer"))
   ->mergeBindings($entry_customers)
   ->count();


Answered By - TsaiKoga
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, January 19, 2022

[FIXED] Laravel Cannot use object of type stdClass as array when using Query Builder

 January 19, 2022     eloquent, laravel, laravel-5, laravel-query-builder, php     No comments   

Issue

Short Version of question:

I received Cannot use object of type stdClass as array when using Query Builder, but works fine with Eloquent. How I solve that issue?

Long Version of question:

When I using method 1 there is a error.

Error : Cannot use object of type stdClass as array (This gives for view foreach start line)

But when I using method 2 there is no error.

I wanted to know why it return error when I using method 2. How I correct it?

Method 01 (In Controller)

$parents = DB::table('stuparents');
$parents = $parents->orderBy('first_name');
$parents = $parents->get();

Method 02 (In Controller)

$parents = StuParents::orderBy('first_name');
$parents = $parents->get();

In View

@foreach($parents as $student)

//Code

@endforeach

This is the var_dump of both methods.

Method 01

object(Illuminate\Support\Collection)#316 (1) { ["items":protected]=> array(2) { [0]=> object(stdClass)#323 (6) { ["id"]=> int(2) ["first_name"]=> string(6) "Nayani" ["last_name"]=> string(10) "Kumarihami" ["student_id"]=> int(9) ["created_at"]=> NULL ["updated_at"]=> NULL } [1]=> object(stdClass)#318 (6) { ["id"]=> int(1) ["first_name"]=> string(5) "Nimal" ["last_name"]=> string(8) "Appuhami" ["student_id"]=> int(4) ["created_at"]=> NULL ["updated_at"]=> NULL } } }

Method 2

object(Illuminate\Database\Eloquent\Collection)#329 (1) { ["items":protected]=> array(2) { [0]=> object(App\StuParents)#330 (25) { ["table":protected]=> string(10) "stuparents" ["connection":protected]=> string(5) "mysql" ["primaryKey":protected]=> string(2) "id" ["keyType":protected]=> string(3) "int" ["incrementing"]=> bool(true) ["with":protected]=> array(0) { } ["withCount":protected]=> array(0) { } ["perPage":protected]=> int(15) ["exists"]=> bool(true) ["wasRecentlyCreated"]=> bool(false) ["attributes":protected]=> array(6) { ["id"]=> int(2) ["first_name"]=> string(6) "Nayani" ["last_name"]=> string(10) "Kumarihami" ["student_id"]=> int(9) ["created_at"]=> NULL ["updated_at"]=> NULL } ["original":protected]=> array(6) { ["id"]=> int(2) ["first_name"]=> string(6) "Nayani" ["last_name"]=> string(10) "Kumarihami" ["student_id"]=> int(9) ["created_at"]=> NULL ["updated_at"]=> NULL } ["casts":protected]=> array(0) { } ["dates":protected]=> array(0) { } ["dateFormat":protected]=> NULL ["appends":protected]=> array(0) { } ["events":protected]=> array(0) { } ["observables":protected]=> array(0) { } ["relations":protected]=> array(0) { } ["touches":protected]=> array(0) { } ["timestamps"]=> bool(true) ["hidden":protected]=> array(0) { } ["visible":protected]=> array(0) { } ["fillable":protected]=> array(0) { } ["guarded":protected]=> array(1) { [0]=> string(1) "*" } } [1]=> object(App\StuParents)#331 (25) { ["table":protected]=> string(10) "stuparents" ["connection":protected]=> string(5) "mysql" ["primaryKey":protected]=> string(2) "id" ["keyType":protected]=> string(3) "int" ["incrementing"]=> bool(true) ["with":protected]=> array(0) { } ["withCount":protected]=> array(0) { } ["perPage":protected]=> int(15) ["exists"]=> bool(true) ["wasRecentlyCreated"]=> bool(false) ["attributes":protected]=> array(6) { ["id"]=> int(1) ["first_name"]=> string(5) "Nimal" ["last_name"]=> string(8) "Appuhami" ["student_id"]=> int(4) ["created_at"]=> NULL ["updated_at"]=> NULL } ["original":protected]=> array(6) { ["id"]=> int(1) ["first_name"]=> string(5) "Nimal" ["last_name"]=> string(8) "Appuhami" ["student_id"]=> int(4) ["created_at"]=> NULL ["updated_at"]=> NULL } ["casts":protected]=> array(0) { } ["dates":protected]=> array(0) { } ["dateFormat":protected]=> NULL ["appends":protected]=> array(0) { } ["events":protected]=> array(0) { } ["observables":protected]=> array(0) { } ["relations":protected]=> array(0) { } ["touches":protected]=> array(0) { } ["timestamps"]=> bool(true) ["hidden":protected]=> array(0) { } ["visible":protected]=> array(0) { } ["fillable":protected]=> array(0) { } ["guarded":protected]=> array(1) { [0]=> string(1) "*" } } } }

Solution

I'm guessing that in the code where you have something like {{ $student['something'] }} is where the error is actually being caused.

The database query builder method get() returns an instance of Illuminate\Support\Collection where each entry is a stdClass and not an array. To access columns, use properties not indexes.

@foreach ($parents as $student)
    {{ $student->column }}
@endforeach

To quote the documentation:

The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP StdClass object. You may access each column's value by accessing the column as a property of the object.

https://laravel.com/docs/5.3/queries#retrieving-results



Answered By - ollieread
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to check if table is already joined in Laravel Query Builder

 January 19, 2022     laravel, laravel-5, laravel-query-builder, php     No comments   

Issue

I created a query. I want to join my table with students table:

$query->leftJoin('students', 'learners.student_id', '=', 'students.id');

But I don't know my table joined before or not. How should I do that?


Solution

I found this solution:

function joined($query, $table) {
    $joins = $query->getQuery()->joins;
    if($joins == null) {
        return false;
    }
    foreach ($joins as $join) {
        if ($join->table == $table) {
            return true;
        }
    }
    return false;
}

if ( joined($query, 'students') ) {
    $query->leftJoin('students', 'learners.student_id', '=', 'students.id');
}


Answered By - Roham Rafii
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing