Forcing Partition Query Using Laravel - laravel

Hi I am currently writing a query where I would like to force the partition that the query uses. I know this code is working in MySQL but I don't know how I would write this using laravel.
This is the MySQL code I would use to force the partition
PARTITION (p46)
I have tried writing the following in Laravel but it doesn't seem to be working
->raw('PARTITION (p46)')
I'm not sure if raw is even a method you can use in laravel which is why it probably doesn't work.
I am using this partition enforcement instead of using the below code, it makes my queries much faster.
->where('venue_id', 46)
My table is partition using HASH(venue_id) and I have tried using the MySQL code and that is working perfectly.
Thank you in advance if you have a solution for this, I haven't been able to find anywhere which explains how to do this.
Here is my full laravel query to give you some context:
$bodyVisitors->selectRaw('SUM(visitors_new) AS new, SUM(visitors_total) AS total')
->raw('PARTITION (p' . $venue_filter . ')')
->where('day_epoch', '>=', $body_start)
->where('day_epoch', '<', $body_end)
->get();
The ->raw() is being ignored is there anyway to make this work? I am fine if the answer is no, I will just stop using laravel to write those queries.

I also suffer the partition problem for whole day...
The way I solve is
select the max timestamp and max ID for T1 then left join it to the T2 on T1.timestamp and ID
Hope that my suggestion would give a some help...
I am still writing the eloquent script almost done :'(

Try like this in your Eloquent Model:
$table = $this->getConnection()->getTablePrefix() . $this->getTable();
$table .= ' PARTITION ({your partition})';
$this->newQuery()->from($table)->where()->get();
that will be making a query like this:
select * from table PARTITION (xxxxxx) where

Try adding this scope
{
$query->from($partition);
}
and $partition is a name of your partition. Try $partition = 'p46' in your case

Related

Laravel 5: Grabbing a single record from a query using `take`

Right now, I am using Eloquent like this: MobileAppUsers::where('store', '=', 'store_name')->first(); It turns out I don't need to check the store_name because the entire table is within that store's database, so I just want the single record that will be there (there will only be 1).
Without changing any other logic, would the equivalent of MobileAppUsers::where('store', '=', 'store_name')->first(); (ignoring the store_name) be :
MobileAppUsers::take(1)->get(); ?
you can use this
MobileAppUsers::first();
Regards, I hope this help you

Elquent Relation Limit records

I'm trying to send API with certain number of records
$category->products
I tried to use limit() or take() but it fails
so is there any smart solution than go to pivot and select it with limit ??
Copy data to a new collection.
$collection =$category->products;
you can now send the number of times you want using take ().
for example;
$collection->take(5);
if your question is different please explain it more clearly.
I found the solution I was easy
$category->products()->limit(2)->get()->all()
that's all

Eloquent deleting more records than intended?

Post::whereReplyTo($request->input('reply_to'))
->orderBy('updated_at', 'desc')
->offset(Config::PAGE_SIZE * Config::MAX_PAGES)
->take(1024)
->delete();
I intend to fire this when post count reaches 4 in order to maintain a maximum of 4 posts, in this case.
Problem is it deletes ALL posts, not only those that I intended to delete
I'm becoming frustrated, why is this happening? theres no error, and I toSql'd the query and nothing is wrong, the selction part is correct, I tried it, so why is it deleting ALL posts???
Well, if your research is correct, you should still be able to do it with two steps:
$delete_posts = Post::select('id')->whereReplyTo($request->input('reply_to'))
->orderBy('updated_at', 'desc')
->offset(Config::PAGE_SIZE * Config::MAX_PAGES)
->take(1024)
->get()->toArray();
Post::whereIn('id', $delete_posts)->delete();
I think I'm on to something
I appended a listener to log the last query after running my Delete
the result was:
delete from `a2_posts` where `reply_to` = ? order by `updated_at` desc limit 1024
so where is my offset? I googled around and I think you cant use offset + delete.
retarded? yes, very much so.
This is why I like Mongo better.
It makes more sense.
Source: Mysql delete statement with limit
so what I think I'll do is query, then iterate, then delete.
SQL is pure genius sometimes I swear to God.

Doctrine 2 Add custom field using DQL is possible?

I can't solve this problem. I have a very large code for filters using a QueryBuilder instance
$qb = new QueryBuilder();
$qb->select('item)->from->("BundleExample:Item");
$qb->andWhere("item.idProvince = {$idProvinde");
if($price)
$qb->andWhere("price betwenn..");
Ok , there is too much lines.
Now i need to add a virtual column (distance) or overwrite a current field value.
$qb->select('item, COS(..) as distance')
As i understand , i need to create a ResultSetMapping , but i have to re-do all the filtering process and this is very annoying.
Any ideas?
thanks
You don't have to use native queries nor RSM, as Doctrine is capable of returning mixed/hybrid result sets: Pure and Mixed Results.

Laravel - Really struggling to understand eloquent

I'm fairly new to Laravel having come over from Codeigniter and for the most part I really like it, but I really can't get my head around Eloquent.
If I want to do a simple query like this:
SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id
I try doing something like this (with a "belongs to"):
$site = Site::with('tweeter')->find($site_id);
But now I have two queries and an IN() which isn't really needed, like so:
SELECT * FROM `site` WHERE `id` = '12' LIMIT 1
SELECT * FROM `tweeter` WHERE `id` IN ('3')
So I try and force a join like so:
$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->find($site_id);
And now I get an error like so:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous
SQL: SELECT * FROM `site` INNER JOIN `tweeter` ON `tweeter`.`id` = `site.tweeter_id` WHERE `id` = ? LIMIT 1
Bindings: array (
0 => 12,
)
It's obvious where the error is, the where needs to use something like "site.id = ?". But I can't see anyway to make this happen?
So i'm just stuck going back to fluent and using:
DB::table('site')->join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id','=',$site_id)->first()
I guess it's not a massive problem. I would just really like to understand eloquent. I can't help but feel that i'm getting it massively wrong and misunderstanding how it works. Am I missing something? Or does it really have to be used in a very specific way?
I guess my real question is: Is there anyway to make the query I want to make using Eloquent?
I actually find this behaviour advantageous. Consider this (I'll modify your example). So we have many sites and each has many tweeters. Each site has a lot of info in the DB: many columns, some of them text columns with lots of text / data.
You do the query your way:
SELECT * FROM site INNER JOIN tweeter ON tweeter.id = site.tweeter_id
There are two downsides:
You get lots of redundant data. Each row you get for a tweeter of the same site will have the same site data that you only need once so the communication between PHP and your DB takes longer.
How do you do foreach (tweeter_of_this_site)? I'm guessing you display all the sites in some kind of list and then inside each site you display all of it's tweeters. You'll have to program some custom logic to do that.
Using the ORM approach solves both these issues: it only gets the site data once and it allows you to do this:
foreach ($sites as $site) {
foreach($site->tweeters as $tweeter) {}
}
What I'm also saying is: don't fight it! I used to be the one that said: why would I ever use an ORM, I can code my own SQL, thank you. Now I'm using it in Laravel and it's great!
You can always think of Eloquent as an extension of Fluent.
The problem you're running into is caused by the find() command. It uses id without a table name, which becomes ambiguous.
It's a documented issue: https://github.com/laravel/laravel/issues/1050
To create the command you are seeking, you can do this:
$site = Site::join('tweeter', 'tweeter.id', '=', 'site.tweeter_id')->where('site.id', '=', $site_id)->first($fields);
Of course, your syntax with join()->find() is correct once that issue fix is adopted.

Resources