I need to pass some records from one table to another but I also need to delete those records that have been copied.
The thing that makes this complex is that I need to grab a random bunch of records!
This is what I have been trying the past 2 hours:
$temps = DB::table('temps')->inRandomOrder()->take(3)->get();
foreach ($temps as $temp) {
DB::table('videos')->insert(
[
'idd' => $temp->idd,
'title' => '',
]
);
}
foreach($temps as $temp){
DB::table('temps')->where('idd', '=', $temp->idd)->get()->delete();
}
return 'success';
If I only want to insert, no problem.
If I want to delete specific records or the whole table, no problem.
However, it's not working if I try to delete the randomly inserted records. What am I doing wrong?
Executing a delete() after the get() method is incorrect:
foreach($temps as $temp){
DB::table('temps')->where('idd', '=', $temp->idd)->delete();
}
or a single query without the loop:
DB::table('temps')->whereIn('idd', $temps->pluck('idd'))->delete();
Related
Dears,
Actually, I would like to know the best solution to manipulate BIG DATA in LARAVEL/MYSQL.
In my system, am uploading daily excel file (5K rows) into my DB, in case I find the same row in my table so I don't insert it, and if I find the same row, I changed the uploaded date in my DB.
Every time I upload the excel, am checking each row if exist in my table (table contain > 50K) with a normal array like the below
$res = policies::where('phone', '=', $row['phone'])
->where('draft_no', '=', $row['draftno'])
->where('due_date', '=', $duedate)
->where('status', '=', $stat)
->where('bord_date', '=', $borddate)
->where('amount', '=', $row['amnt'])
->where('remarks', '=', $row['remarks'])
->exists();
if(!$res) {
// insert row ($table->save())
}
else {
//update uploaded date to this row.
}
this process takes lots of time bcz each time is checking the table. I tried to use array_chunk in order to insert, but still, the load is big (15 min to 20 min) to finish
Your advice are highly appreciated.
Thanks
You can create an hash of each row and store along with the row. Then check only the row with given hash.
For instance try this stub of code
foreach ($rows as $row) {
$hash = md5($row['phone'] . $row['draft_no'] . $row['due_date'] ...);
$res = Policiess::where('hash', $hash);
if (!$res) {
// create a new row and store the `$hash` in `hash` column
} else {
//update uploaded date to this row
}
}
if you not add new record same excel then not need check in database. but you add same excel file new record then insert all record after update this excel file
Why don't use laravel default eloquent method updateOrCreate.
Hope you already read about it if you don't you can read it from documentation other-creation-methods.
Let me explain what actually it does.
It Accepts an array of values and checks value is already in the database if it's already in the database it will update these values and also update column updated_at or if it's not already in the database, it will create a new entry in the table.
See eg below :-
policies::updateOrCreate(['value'=>1,'value'=>2,'so on...']);
and dont forget to add protected $fillable = [your column] , Because it's use $fillable for this.
I need to delete multiple rows and then reordering the next database records.
ELDI_Order it's not an autoincrement.
This is my MODEL for DELETING ONE RECORD
public function delete_one_record($id)
{
$this->db->select('ELDI_Order');
$this->db->where("ELDI_Id", $id);
$eldi_order = $this->db->get('elem_diccio')->row()->ELDI_Order
// Delete that record
$this->db->delete('elementos_diccionario', array('ELDI_Id' => $id));
// Reorder ELDI_Order for the rest of the records
$this->db->set('ELDI_Order', 'ELDI_Order-1', FALSE);
$this->db->where('ELDI_Order >', $eldi_order);
$this->db->update('elem_diccio');
}
MODEL for DELETING MULTIPLE RECORDS
function eliminar_varios_elementos_diccionario($ids)
{
$this->db->where_in('ELDI_Id', explode(",", $ids));
$this->db->delete('elem_diccion');
// Code for reordering
}
For example, if I delete rows 2 and 8 (the 4th) I want to substract 1 to the column ELDI_Order of prueba_3 because it moved "1 place", and 2 from prueba_5 because it "moved" 2 places because I deleted 2 records.
Thanks for your help and time!
Just use your delete_one_record function and a foreach. I can't see a way to inefficiently reorder multiple items at a time - so its not too bad to do them individually.
function eliminar_varios_elementos_diccionario($ids)
{
if (!is_array($ids)) {
$ids = explode(",", $ids);
}
foreach ($ids as $id) {
$this->delete_one_record(intval($id)); // assummed function is in same model
}
}
Suggestion: think about using transactions.
I've set up a database and want to update the column status for each row in my UsersController:
I started with this:
User::where('id', '=', 1)->update(['status' => $status]);
This is working, but I need some loop to change all the rows, something like this:
foreach $id from the table
run some code to change individual $status variable
set individual $status value in the 'status' column in each row:
User::where('id', '=', $id)->update(['status' => $status])
end foreach
So for me its unclear how to go through the table via the foreach. Then save the calculated status from my code to each individual id?
#Serge solution is fine for few records but you should be able to use chuck as #ceejayoz suggested
User::chunk(100, function ($users) {
$users->each(function ($user) {
$user->status = getStatus($user);
$user->save();
});
});
Unless the table contains millions of rows... a simple procedural way of doing it is...
$users = Users::get(); // Gets a collection of all users...
foreach ( $users as $user ) {
//compute your status
$user->status = get_your_user_status($user->id);
$user->save();
}
You could also consider using a more functional approach with map for example...
I'm running this code on Laravel. I'm adding filters/ordering if I receive them and I'm altering the query before running it and then paginate the results.
$aDatas = DB::table('datas');
if (!empty($aLocations)) {
foreach ($aLocations as $oLocation) {
$aDatas->orWhere('pc', '=', $oLocation->pc);
}
}
if (!empty($oFilters->note)) {
$aDatas->where('note', '>=', $oFilters->note);
}
if (!empty($oFilters->nb_comments)) {
$aDatas->where('nb_comments', '>=', $oFilters->nb_comments);
}
if (!empty($oOrder->type)) {
$aDatas->orderBy($oOrder->type, $oOrder->sort);
}
// echo $aDatas->where('note', '>=', 5)->count() ????
It's working fine.
But I'd like to use these results to count several parts of it.
The last line shows what I tried to do, counting how many rows in these filtered results have a note >= 5. But doing this will actually filter my original data.
I thought about assigning $aDatas to another variable and then count on this, but I'll have many counts and that seems dirty.
Is there a sweet way to do this ?
Just save your datas an replace the last line with this:
$datas =$aDatas->where('note', '>=', 5)->get();
echo $datas->count();
//use datas here for more action.
For all of your requirement, you might want to resolve in making several queries because a single query will not be able to do that(based from what I know)
//this is to get your total of note greater than 5
$query = DB::table('datas');
$query->where('note', '>=', 5);
$data = $query->paginate(10);
$count = $data->getTotal();
to get your other data
If you are working with pagination, use getTotal() instead
$query = DB::table('datas');
$query->select(
DB::raw('COUNT(stars) AS count'),
DB::raw('starts'),
);
$query->where('notes', '>=', 5);
$query->groupBy('stars');
$data = $query->get();
I have a Poll table, a Students table, and a pivot table between them that includes a token and their three votes.
public function students()
{
return $this->belongsToMany('Student', 'polls_students')->withPivot('token','first','second','third');
}
While working out saving the poll results, I came across some odd behavior that I don't quite understand. I'm hoping somebody can explain what it is I'm missing:
$poll = Poll::find(Input::get('poll_id'));
foreach($poll->students()->where('students.id', '=', Input::get('student_id'))->get() as $student){
var_dump($student->pivot->token);
}
$student = $poll->students()->where('students.id', '=', Input::get('student_id'))->get();
var_dump($student->pivot->token);
In the above code, the foreach loop will successfully display the token, where the second one throws the exception Undefined property: Illuminate\Database\Eloquent\Collection::$pivot
What am I missing? Are these two calls not logically creating the same object? How is 'pivot' working on the first and not the latter?
You first example:
$poll = Poll::find(Input::get('poll_id'));
foreach($poll->students()->where('students.id', '=', Input::get('student_id'))->get() as $student){
var_dump($student->pivot->token);
}
Here $poll->students() retrieves a collection and because of foreach loop you get a single object in your $student variable and you can use $student->pivot->token
You second example:
$student = $poll->students()->where('students.id', '=', Input::get('student_id'))->get();
var_dump($student->pivot->token);
Here you are doing same thing, using $poll->students() you are getting a collection but this time you are not using a loop and trying to do same thing using $student->pivot->token but it's not working because you didn't define any index from which you want to get the pivot->token, if you try something like this
$student->first()->pivot->token
Or maybe
$student->get(1)->pivot->token
Or maybe you can use first() instead of get() like this
$student = $poll->students()->where('students.id', '=', Input::get('student_id'))->first();
Then you can use
$student->pivot->token
Remember that, get() returns a collection even if there is only one record/model.
$poll = Poll::find(Input::get('poll_id'));
foreach($poll->students as $student){
var_dump($student->pivot->where('student_id',$student->id)->where('poll_id',$poll->id)->first()->token);
}