laravel sql subquery - sql

I have read the docs about raw queries but they say nothing about building subqueries. Can't I just enter raw sql inside a controller action or model at worst?)
i have two tables, rates and performance.
I cant get to write in Laravel parlance (either query builder or eloquent or raw query) in the controller (or model) the following sql subquery
SELECT ratedescription
FROM rates
WHERE rates.digit
IN (SELECT
performance.score
FROM performances
where performances.id = $i);
the $i is a parameter that goes into the method in the controller
This question is NOT for bouty. I have never said that, and it is SO who does it without even asking me.

I didn't use Laravel in a long time but can't you manage to do the same this with query builder?
laravel docs
Something like :
Rate::select("ratedescription")->whereIn("digit", function($query) {
$query->from("performances")->select("score")->where(...);
})->get();
My answermight be wrong since I'm didn't use either laravel or php for some time now but I hope it can help.
Have a nice day.

Related

IQueryable Extension to Generate Temporal Table "AS OF" Queries

Having failed to find a satisfying solution, let me post this here:
We're using NHibernate as our ORM and are just beginning to use Sql Server temporal tables. We therefore need some kind of extension to IQueryable (or the HQL Builder or an InterceptingProvider or something) that will allow us to add the "AS OF" clause to our queries, something like
var results = session.Query<Company>
.Where(c => c.Name == "FogCreek")
.AsOf(DateTime.Today.AddYears(-1));
I've been struggling with it too and gave up as I lost too much time trying to find better approach...
So far I've injected FOR SYSTEM_TIME AS OF into SQL using custom HqlGeneratorForMethod but this gave me invalid SQL expression. So I had to fix it in OnPrepareStatement. This is hacky and not elegant solution but works for most simple cases.
Please look at my solution here and feel free to reply if you find better solution

graphql optimization

Everyone!
Is it possible to access info and context for nodedefination. Where I can have abstract syntax tree (AST). I actually need it to optimize my Object (which is node) requests.
For example: if I have the next graphql query:
query { node(id:'some_id'){ name, surname, friends{ edges node{ { name,
surname} }}, posts{edges{ node{ id, text} }}}.
So in that case first I have to make SQL query for my person which is node, then I have to ask SQL friends of my person and another SQL query for posts that were made by person. And probably later posts of all friends. That actually is very expensive. I would love to check fields in request and build a single SQL query.
How would be better to do it?
Thank you!
DataLoader can help you with this, without having to inspect the query. Essentially it enables batching of expensive calls. You write a batch function which is called for each batch, in this function you build a single SQL query of all the individual calls. It's very nice!
In essence it allows you to make naive, to the point, DB requests in your resolvers, and still get the performance benefit of a single DB query. Hope this makes sense?
Read the docs here and give it a try (it's awesome) https://github.com/facebook/dataloader

Bookshelfjs ORM How to get or see SQL statement its building

When building ORM query, I want to see what the actual (raw) query is that is executed.
For example in Rails we can do like this:
User.where(name: 'Oscar').to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'Oscar'
This feature present in Bookshelfjs? or any other way to get this?
Thanks in advance
Looks like there is no direct way to get SQL statement like Rails produce..
You can use .query() .toSQL() or .query() .toString(). But achieving exact result as in Rails is a bit more complicated as queries may be not complete. The cause is that many statements get applied just before performing the query in Bookshelf. For example Bookshelf relations behave so. Also many plugins use events to apply query statements. If you want to debug the queries then I would suggest you to use Knex#debug instead. For example
model.query(function(qb) {
qb.debug(true);
}).fetch()
It prints the debug info in the console.
Source: from officials bookshelfjs github

Pure SQL queries in Rails view?

I am asked to display some sort of data in my Rails App view with pure SQL query without help of ActiveRecord. This is done for the Application owner to be able to implement some third-party reporting tool (Pentaho or something).
I am bad in SQL and I am not really sure if that is even possible to do something similar. Does anyone have any suggestions?
If you must drop down to pure SQL, you can make life more pleasant by using 'find by sql':
bundy = MyModel.find_by_sql("SELECT my_models.id as id, my_articles.title as title from my_models, my_articles WHERE foo = 3 AND ... ...")
or similar. This will give you familiar objects which you can access using dot notation as you'd expect. The elements in the SELECT clause are available, as long as you use 'as' with compound parameters to give them a handle:
puts bundy.id
puts bundy.title
To find out what all the results are for a row, you can use 'attributes':
bundy.first.attributes
Also you can construct your queries using ActiveRecord, then call 'to_sql' to give you the raw SQL you're using.
sql = MyModel.joins(:my_article).where(id: [1,2,3,4,5]).to_sql
for example.
Then you could call:
MyModel.find_by_sql(sql)
Better, though, may be to just use ActiveRecord, then pass the result of 'to_sql' into whatever the reporting tool is that you need to use with it. Then your code maintains its portability and maintainability.

CakePHP query additions in controller

I am migrating raw PHP code to CakePHP and have some problems. As I have big problems with query to ORM transformation I temporary use raw SQL. All is going nice, but I met the ugly code and don't really know how to make it beautiful. I made DealersController and added function advanced($condition = null) (it will be called from AJAX with parameters 1-15 and 69). function looks like:
switch ($condition) {
case '1':
$cond_query = ' AND ( (d.email = \'\' OR d.email IS NULL) )';
break;
case '2':
$cond_query = ' AND (d.id IN (SELECT dealer_id FROM dealer_logo)';
break;
// There are many cases, some long, some like these two
}
if($user_group == 'group_1') {
$query = 'LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} elseif ($user_group == 'group_2'){
$query = 'A LITLE BIT DIFFERENT LONG QUERY WITH 6+ TABLES JOINING' . $cond_query;
} else {
$query = 'A LITLE MORE BIT DIFFERENT LONG QUERY WITH 10+ TABLES JOINING' . $cond_query;
}
// THERE IS $this->Dealer->query($query); and so on
So.. As you see code looks ugly. I have two variants:
1) get out query addition and make model methods for every condition, then these conditions seperate to functions. But this is not DRY, because main 3 big queries is almost the same and if I will need to change something in one - I will need to change 16+ queries.
2) Make small reusable model methods/queries whitch will get out of DB small pieces of data, then don't use raw SQL but play with methods. It would be good, but the performance will be low and I need it as high as possible.
Please give me advice. Thank you!
If you're concerned about how CakePHP makes a database query for every joined table, you might find that the Linkable behaviour can help you reduce the number of queries (where the joins are simple associations on the one table).
Otherwise, I find that creating simple database querying methods at the Model level to get your smaller pieces of information, and then combining them afterwards, is a good approach. It allows you to clearly outline what your code does (through inline documentation). If you can migrate to using CakePHP's find methods instead of raw queries, you will be using the conditions array syntax. So one way you could approach your problem is to have public functions on your Model classes which append their appropriate conditions to an inputted conditions array. For example:
class SomeModel extends AppModel {
...
public function addEmailCondition(&$conditions) {
$conditions['OR'] = array(
'alias.email_address' => null,
'alias.email_address =' => ''
);
}
}
You would call these functions to build up one large conditions array which you can then use to retrieve the data you want from your controller (or from the model if you want to contain it all at the model layer). Note that in the above example, the conditions array is being passed by reference, so it can be edited in place. Also note that any existing 'OR' conditions in the array will be overwritten by this function: your real solution would have to be smarter in terms of merging your new conditions with any existing ones.
Don't worry about 'hypothetical' performance issues - if you've tried to queries and they're too slow, then you can worry about how to increase performance. But for starters, try to write the code as cleanly as possible.
You also might want to consider splitting up that function advanced() call into multiple Controller Actions that are grouped by the similarity of their condition query.
Finally, in case you haven't already checked it out, here's the Book's entry on retrieving data from models. There might be some tricks you hadn't seen before: http://book.cakephp.org/view/1017/Retrieving-Your-Data
If the base part of the query is the same, you could have a function to generate that part of the query, and then use other small functions to append the different where conditions, etc.