laravel where clause value and column name - mysql

How can i do these in laravel query where clause?
select * from table_samples where 1 = id
// basically i can do like where id = 1
select * from table_samples where 1000 > rate
// basically i can do like where rate < 1000
select * from table_samples where 'bogart' = name
// basically i can do like where name = "bogart"
My point is if you interchange the column and value its working on mysql, but if i do this in laravel where clause it doesn't work?
Something like
TableSample::where('1','id')->first();
TableSample::where('1000','>','rate')->first();
TableSample::where('bogart','name')->first();
// throws an error undefined column name 1, 100, and bogart.
// I know laravel . These are the correct query
TableSample::where('id','1')->first();
TableSample::where('rate','<','1000')->first();
TableSample::where('name','bogart')->first();
Is there any where clauses functions in laravel that can accept or determine if you try to interchange the value and column?

You yan use DB::raw() for this.
TableSample::whereRaw('? = id', [1])->first();
Just make sure you use parameter substitution like above to prevent creating sql injection vulnerabilities.
https://laravel.com/docs/5.6/queries#raw-expressions

The whereRaw and orWhereRaw methods can be used to inject a raw where clause into your query
TableSample::whereRaw('1 = id')->first();
https://laravel.com/docs/5.6/queries#raw-methods

Related

How to access columns of subqueries with jooq?

i am having troubles understanding how to access columns from a subquery (MySQL). Here is my code:
Personne personne = Personne.PERSONNE.as("personne");
Evenement evenement = Evenement.EVENEMENT.as("evenement");
Genealogie genealogie = Genealogie.GENEALOGIE.as("genealogie");
Lieu lieu = Lieu.LIEU.as("lieu");
SelectField<?>[] select = { DSL.countDistinct(personne.ID).as("countRs"), lieu.LIBELLE.as("libelleRs"),
lieu.ID.as("idVille") };
Table<?> fromPersonne = evenement.innerJoin(personne).on(personne.ID.eq(evenement.IDPERS))
.innerJoin(genealogie).on(genealogie.ID.eq(personne.IDGEN)).innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDLIEU));
Table<?> fromFamille = evenement.innerJoin(personne).on(personne.IDFAM.eq(evenement.IDFAM))
.innerJoin(genealogie).on(genealogie.ID.eq(personne.IDGEN)).innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDLIEU));
GroupField[] groupBy = { lieu.ID };
Condition condition = //conditionally build, not relevant i think
result = create.select(DSL.asterisk())
.from(create.select(select).from(fromPersonne).where(condition).groupBy(groupBy)
.union(create.select(select).from(fromFamille).where(condition).groupBy(groupBy)))
// i would like something like this but i don't know how: .groupBy(groupBy).fetch();
Basicly what i have is:
SELECT
*
FROM(
(SELECT
countRs, libelleRs, idVille
FROM
fromPersonne
WHERE
-- conditions
GROUP BY lieu.ID)
UNION
(SELECT
countRs, libelleRs, idVille
FROM
fromFamille
WHERE
-- conditions
GROUP BY lieu.ID)
)GROUP BY lieu.ID -- this is where i need help
In a plain MySQL query i would just give an alias to the union and then make a reference to the column i want to group by using the alias but it seems like it does not work like this with JOOQ.
I just need to group the results of the subqueries together but i don't know how to make a reference to the subqueries columns... I am sure i would have to reference my subqueries in objects outside of that "main select" to be able to access the columns or something along those lines but i am lost in all the object types.
You have to assign your derived table to a local variable and dereference columns from it, e.g.
Table<?> t = table(
select(...).from(...).groupBy(...).unionAll(select(...).from(...).groupBy(...))
).as("t");
Field<Integer> tId = t.field(lieu.ID);

How to count all records if use alias in select query?

I use Sphinx with Yii2 and need to query with filter by jSON field.
$query = new \yii\sphinx\Query();
$query->from('announcements');
$query->addSelect("*");
$query->addSelect(new Expression("IN(filters['color'], 'blue', 'red', 'green') AS f_color"));
$query->where("is_active = 1");
$query->andWhere("f_color = 1");
$announces = $query->all();
There is jSON field filters in my Sphinx index. For example:
[filters] => {"brand":"Toyota","model":"Prius","color":"red","price":"12000"... etc]
It works OK. But now I need to make a pagination... and there is a problem when I try to count records before $query->all()
$count = $query->count(); // Return error "no such filter attribute 'f_color'"
Generated query was:
SELECT COUNT(*) FROM announcements WHERE ( is_active = 1 ) AND ( f_color = 1 )
count() by default replaces the select part with * and this is where your alias is defined hence the error.
There are different ways to achieve it like:
use ActiveDataProvider like described here,
use META information like described here
Since you want to make a pagination I would go with the first example.

MySQL where if statement

I'm currently working on an API using node.js and node-mysql.
I start off by grabbing all the parameters that the client sends over like this:
var userId = req.query.userId;
var carType = req.query.carType;
var hasOwnership = req.query.hasOwnership; (optional parameter)
What I would like to do is make a statement so that if the client sends the hasOwnership parameter with the request, my statement will return all the cars that belong to him with the specific car type. Similar to this:
SELECT * FROM cars WHERE car_type=? AND owner_id=?, [carType, userId];
Otherwise it will just return the all the cars that match the car type:
SELECT * FROM cars WHERE car_type=?, [carType];
Is it possible to accomplish something like this in a single query?
Thanks in advance!
You can phrase the query as something like this:
SELECT *
FROM car
WHERE (? is null or car_type = ?) AND
(? is null or owner_id = ?);
Note that this version takes each parameter twice, unless you use named parameters.
A dirty quick solution would be to use an if then else.
if hasOwnership has value the use query #1 else use query #2

Need to convert an array to Integer for a MySQL query in a Rails API

I have a piece of code which fetches the list of ids of users I follow.
#followed = current_user.followed_user_ids
It gives me a result like this [11,3,24,42]
I need to add these to NOT IN mysql query.
Currently, I am getting NOT IN ([11,3,24,42]) which is throwing an error. I need NOT IN (11,3,24,42)
This is a part of a find_by_sql statement, so using where.not is not possible for me in this point.
In rails 4:
#followed = current_user.followed_user_ids # #followed = [11,3,24,42]
#not_followed = User.where.not(id: #followed)
This should generate something like select * from users where id not in (11,3,24,42)
As you comment, you are using find_by_slq (and that is available in all rails versions). Then you could use the join method:
query = "select * from users where id not in (#{#followed.join(',')})"
This would raise mysql errors if #followed is blank, the resulting query would be
select * from users where id not in ()
To solve this whiout specifiying aditional if statements to your code, you can use:
query = "select * from users where id not in (0#{#followed.join(',')})"
Your normal queries would be like:
select * from users where id not in (01,2,3,4)
but if the array is blank then would result in
select * from users where id not in (0)
which is a still valid sql statement and is delivering no results (which might be the expected situation in your scenario).
you can do something like:
#followed = [11,3,24,42]
User.where('id not in (?)', #followed)

Cast function output as column name

I have come across a scenario where I need to "cast" the output of a function as the column name I want to select:
(SELECT
LOWER(DATE_FORMAT(NOW(), '%b'))
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month
Just returns the current month which is expected, but I want this to select the column called "may" in this case.
How would I do this?
Thanks, your answer gave me an idea. I just put the current date into a variable and used that in the query like so:
$thisMonth = strtolower(date('M')) ;
(SELECT
$thisMonth
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month
This is not possible. The name of an entity must be known when the query reaches MySQL.
The easiest option would probably be to determine the column name in whatever language you're using then to just use that. For example, in PHP:
$col = 'someAlias';
$query = "SELECT blah as `{$col}` FROM tbl";
I don't think this is possible.
You could create a view that offers this view on your data so you can they query it more expressively, but you're still going to have to write those 12 subqueries and aliases by hand.
This should work:
$month = LOWER(DATE_FORMAT(NOW(), '%b')); // Results in 'may'
$result = mysql_query('SELECT * FROM $month'); // Returns all records in table 'may'