the problem is,
when I pluck the ids, a collection of ids returned
I need to get only the values
$transferOfficeId = $searchResults->pluck('office_id','office_id');
$vehicleId = $searchResults->pluck('vehicle_id','vehicle_id');
$agencyId = $searchResults->pluck('forAgency_id','forAgency_id');
$userId = $searchResults->pluck('addedBy_user_id','addedBy_user_id');
To get the names of these values by there ids
but here is not allowed because the ids are a collection not a values
$officeName = $bookingTransfersData->pluck('transferOffice.officeName','transferOffice.transfer_office_id')->get($transferOfficeId);
$vehicleName = $bookingTransfersData->pluck('vehicle.vehicleName','vehicle.vehicleName')->get($vehicleId);
$agencyName = $bookingTransfersData->pluck('agency.agencyName','agency.agencyName')->get($agencyId);
$userName = $bookingTransfersData->pluck('user.userName','user.userName')->get($userId);
return view('dashboard.index',compact('searchResults','fromDestinationName','toDestinationName','officeName', 'vehicleName','agencyName','userName'))
->with('i', (request()->input('page', 1) - 1) * 5);
I want to get the values of ids plucked,
to get columns by these ids from tables of each id like transferOfficeId,vehicleId .....
please help.
Related
$projects = Project::find(collect(request()->get('projects'))->pluck('id')); // collect(...)->pluck('id') is [2, 1]
$projects->pluck('id'); // [1, 2]
I want the result to be in the original order. How do I achieve this?
Try $projects->order_by("updated_at")->pluck("id"); or "created_at" if that's the column you need them ordered by.
Referencing MySQL order by field in Eloquent and MySQL - SELECT ... WHERE id IN (..) - correct order You can pretty much get the result and have it order using the following:
$projects_ids = request()->get('projects'); //assuming this is an array
$projects = Project::orderByRaw("FIELD(id, ".implode(',', projects_ids).")")
->find(projects_ids)
->pluck('id'));
#Jonas raised my awareness to a potential sql injection vulnerability, so I suggest an alternative:
$projects_ids = request()->get('projects');
$items = collect($projects_ids);
$fields = $items->map(function ($ids){
return '?';
})->implode(',');
$projects = Project::orderbyRaw("FIELD (id, ".$fields.")", $items->prepend('id'))
->find($projects_ids);
The explanation to the above is this:
Create a comma separated placeholder '?', for the number of items in the array to serve as named binding (including the column 'id').
I solve this by querying the data one by one instead mass query.
$ids = collect(request()->get('projects'))->pluck('id');
foreach($ids as $id){
$projects[] = Project::find($id);
}
$projects = collect($projects);
$projects->pluck('id');
I have to do this manually because laravel collection maps all the element sorted by using ids.
I have a asset_request table with fields id and request_id.
I want to select multiple rows with specific ids.
$ids = $request->ids // 5,6
I want to select only rows with ids of 5 and 6 in request table
$ids = $request->ids;
$asset_request = asset_request::whereIn('id',array($ids))->first(); //gets only 6th row.
I need to get all rows matching the given ids.
To clarify after a chat discussion with the Op:
The Op was passing back a string request, therefore, the Op needed to change the following:
$id = $request->id;
$ids = str_split(str_replace(',', '', $id));
$asset_request = asset_request::whereIn('id', $ids)->get();
First you are calling the first method which will return only the first row matched.
You need to call get method to get all rows matched.
Secondly if you are sending ids as a comma separated string you need to convert it to array using explode.
$ids = $request->ids;
$asset_requst = asset_request::whereIn('id', explode(",", $ids))->get();
DB::table('asset_request')
->whereIn('id', (array) $request->ids)
->get();
or
TableModel::whereIn('id', (array) $request->ids)->get();
I am developing a php project using Laravel 5.2. In my app I am retrieving records from database using manual query. But I am having a problem with retrieving records by using where in statement with csv.
Example how I am retrieving
$csv = "1,3,5";
$sql = "SELECT * FROM `items` WHERE `id` IN (?)";
$rows = DB::select($sql,[$csv]);
As you can see above I am retrieving three rows. But it returns only one row where id is 1. Why is that?
You can't do it like that. Each entry in your csv is a separate parameter, so for your code you would actually need IN (?, ?, ?), and then pass in the array of values. It would be pretty easy to write the code to do this (explode the string to an array, create another array of question marks the same size, put it all together).
However, you are using Laravel, so it would be easier to use the functionality Laravel provides to you.
Using the query builder, you can do this like:
$csv = "1,3,5";
// turn your csv into an array
$ids = explode(",", $csv);
// get the data
$rows = DB::table('items')->whereIn('id', $ids)->get();
// $rows will be an array of stdClass objects containing your results
dd($rows);
Or, if you have an Item model setup for your items table, you could do:
$items = Item::whereIn('id', $params)->get();
// $items will be a Collection of Item objects
dd($items);
Or, assuming id is the primary key of your items table:
// find can take a single id, or an array of ids
$items = Item::find($params);
// $items will be a Collection of Item objects
dd($items);
Edit
If you really want to do it the manual way, you could use a loop, but you don't need to. PHP provides some pretty convenient array methods.
$csv = "1,3,5";
// turn your csv into an array
$ids = explode(",", $csv);
// generate the number of parameters you need
$markers = array_fill(0, count($ids), '?');
// write your sql
$sql = "SELECT * FROM `items` WHERE `id` IN (".implode(',', $markers).")";
// get your data
$rows = DB::select($sql, $ids);
$pidArray contains product ID's, some of those product ID's can be the same. I.E: 34 34 56 77 99 34. As is, it appears the whereIn method does not return results for a productId it has already found in $pidArray, even if it has a different index.
$productDataForOrder = Product::whereIn('id', $pidArray)->get(['id','price']);
$totalAmount = $productDataForOrder->sum('price');
$productDataForOrder now contains product data, but only for unique ProductID's in $pidarray. So when sum function is run, the sum is wrong as it does not take into account the price for multiple instances of the same productID.
The following code also does not return objects for every product ID in the array which are the same. So if $pidArray contains three identical product ID's, the query will only return a collection with one object, instead of three.
$query = Product::select();
foreach ($pidArray as $id)
{
$query->orWhere('id', '=', $id);
}
$productDataForOrder = $query->get(['id','price']);
$totalAmount = $productDataForOrder->sum('price');
You're not going to be able to get duplicate data the way that you're trying. SQL is returning the rows that match your where clause. It is not going to return duplicate rows just because your where clause has duplicate ids.
It may help to think of it this way:
select * from products where id in (1, 1)
is the same as
select * from products where (id = 1) or (id = 1)
There is only one record in the table that satisfies the condition, so that is all you're going to get.
You're going to have to do some extra processing in PHP to get your price. You can do something like:
// First, get the prices. Then, loop over the ids and total up the
// prices for each id.
// lists returns a Collection of key => value pairs.
// First parameter (price) is the value.
// Second parameter (id) is the key.
$prices = Product::whereIn('id', $pidArray)->lists('price', 'id');
// I used array_walk, but you could use a plain foreach instead.
// Or, if $pidArray is actually a Collection, you could use
// $pidArray->each(function ...)
$total = 0;
array_walk($pidArray, function($value) use (&$total, $prices) {
$total += $prices->get($value, 0);
});
echo $total;
The whereIn method only limits the results to the values in the given array. From the docs:
The whereIn method verifies that a given column's value is contained within the given array
Id make a query variable and loop through the array adding to the query variable in each pass. Something like this:
$query = Product::select();
foreach ($pidArray as $id)
{
$query->where('id', '=', $id);
}
$query->get(['id','price']);
Here is a code that would work for your use case expanding on #patricus
You first fetch an array of key as id and value as price from the products table
$prices = Product::whereIn('id', $pidArray)->lists('price', 'id');
$totalPrice = collect([$pidArray])->reduce(function($result, $id) use ($prices) {
return $result += $prices[$id];
}, 0);
4 for on on my applications with Doctrine.
In there I'm using the following doctrine command to retrieve person object collection
//query
$people = $q->execute();
This return 20 objects. The primary key of the person object is a composite key with three attributes. Those are
id
department_id
name
I need to get person objects by searching in it as follows.
$id = 10;
$department_id = 1;
$name = "abc";
$people->get($id, $department_id, $name);
But this doesn't work and not give correct results. I tried with this and it gives null results which seems my collections primary key is not set.
$people->getKeyColumn();
I don't want to go through a foreach loop in collection and process it because when I deal with about 500 people, it slow down my application.
Can some one help me with this issue to get values from a doctrine collection.
Can you use something like this?
$people = Doctrine::getTable('Persons')
->createQuery()
->where('id = ? AND department_id = ? AND name = ?', array($id, $department_id, $name))
->execute();
It will get you a DoctrineCollection already filtered by the parameters provided.
'Persons' here is a Doctrine model name, not a table name from mySQL.
You can also use Doctrine's magic finders findBy*():
$people = Doctrine_Core::getTable('Persons')
->findByIdAndDepartmentIdAndName($id, $department_id, $name);