Query builder not display variable? - mysql

I running this code :
$id = 1;
$email = 'email#gmail.com';
$user = DB::table('users')->where([
['id', '=', $id],
['email', '=', $email]
])->toSql();
dd($user);
But query builder print is :
select * from `users` where (`id` = ? and `email` = ?)
Why not print is:
select * from `users` where (`id` = 1 and `email` = email#gmail.com)

the query builder inserts the characters in place of the values to protect you from the sql injections, then he himself will set the values to you as needed, and you will get the finished result, and the fact that you are displayed on the screen is simply viewing the query queries

That's how toSql() method works. It just shows you prepared query but doesn't execute it.
To execute the query, do use get(), find(), first() or similar method:
$user = DB::table('users')->where([
['id', '=', $id],
['email', '=', $email]
])->first();

Query Builder inserts the characters in place of the values to protect you from the SQL Injections.I believe #Дмитрий-Смирнов answered your query well.
Rather then using raw SQL use model directly you may cut-down your line of code using the below code:
$id = 1;
$email = 'email#gmail.com';
$user = User::where('id',$id)
->where('email',$email)
->get();
dd($user);

Related

Laravel's Database Query Builder

I am trying to write a MySQL select query using Laravel's Database Query Builder
I have this mysql query:
SELECT * FROM `tweets` WHERE `user_id` = 1 OR `user_id` in (SELECT `follows_id` from `follows` where `user_id` = 1)
I am trying to write it for Laravel
$users = DB::table('tweets')
->where('user_id', '=', 1)
how can this be done?
You can do something like this even though it looks ugly.
$tweets = DB::table('tweets')
->where('user_id', 1)
->orWhereIn('user_id', DB::table('follows')->select('follows_id')->where('user_id', 1)->pluck('follows_id'))
->get();
I would suggest a SQL rewrite as OR and IN(SELECT ...) tends to optimize badly.
The SQL result might be wrong as you didn't provide example data and expected result see Why should I provide a Minimal Reproducible Example for a very simple SQL query? for providing those.
SELECT
tweets.*
FROM
tweets
WHERE
tweets.user_id = 1
UNION ALL
SELECT
tweets.*
FROM
tweets
INNER JOIN
follows ON tweets.user_id = follows.follows_id
WHERE
follows.user_id = 1
I believe the following Laraval code should do that. But not sure as i didn't program in Laravel for some time now.
<?php
$first = DB::table('tweets')
->select('tweets.*')
->where('user_id', '=', 1);
$second = DB::table('tweets')
->select('tweets.*')
->join('follows', 'tweets.user_id', '=', 'follows.follows_id')
->where('follows.user_id ', '=', 1)
->union($first)
->get();
?>

Codeigniter multi select query

I have tried to make codeigniter query from mysql query
my mysql query is:
select *
from class_routine
where
semester='$semester'
and day='$day'
and time_schedule='$time_schedule'
and (batch='$batch' or section='$section' or teacher='$teacher' or room='$room');
for above query what will be the codeigniter query ?
I will use this query in model.
First, you should consider looking at the Documentation before asking any question, then specify what you've looked at and what you did try, posting your code.
Anyways, try this and let me know:
$this->db->where(array('semester' => $semester, 'day' => $day, 'time_schedule' => $time_scehdule));
$this->db->where("batch = $batch OR section = $section OR teacher = $teacher OR room = $room", NULL, FALSE);
$result = $this->db->get('class_routine')->result();
When in doubt is perfectly safe to use a normal query:
$result = $this->db->query("SELECT * FROM ....")->result();

mysql join ON and AND to laravel eloquent

I've been able to get the query result I need using the following raw sql:
select `person`.`id`, `full_name`, count(actions.user_id) as total
from `persons`
left join `actions`
on `actions`.`person_id` = `persons`.`id`
and `actions`.`user_id` = $user
where `type` = 'mp'
group by `persons`.`id`
But I haven't been able to get it working in eloquent yet.
Based on some similar answers, I'd tried functions within ->where() or leftJoin(), but the count of each person's actions isn't yet being filtered by $user. As it stands:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', 'persons.id')
->where('actions.user_id', $user);
})
->groupBy('persons.id')
->where('type', 'foo')
//->where('actions.user_id', '=', $user)
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
I'm at least heading in roughly the right direction, right...?
If it's relevant, the Persons.php model has two actions relationships:
public function actions()
{
return $this->hasMany('Action');
}
public function actionsUser($id)
{
return $this->hasMany('Action')->where('user_id', $id);
}
So, for reference, I solved it like so:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', '=', 'persons.id')
->where('actions.user_id', '=', "$user");
})
->groupBy('persons.id')
->where('type', 'foo')
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
The ->where() clause within leftJoin, oddly, needs the speech marks for the variable to be passed through the sql query correctly (likewise, '2' doesn't seem to work while "2" does).
I found that the where doesn't always work on the leftJoin clause
If in the future you get any trouble with it, I'd suggest you using this:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', '=', 'persons.id')
->on('actions.user_id', '=', "$user");
})
->groupBy('persons.id')
->where('type', 'foo')
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
Hope it helps someone.
When laravel eloquent just start getting complex like this
For more flexibility and readability I'll just use plain sql statement then hydrate the results.
$sql = "
SELECT `person`.`id`,
`full_name`,
count(actions.user_id) AS total
FROM `persons`
LEFT JOIN `actions`
ON `actions`.`person_id` = `persons`.`id`
AND `actions`.`user_id` = $user
WHERE `type` = 'mp'
GROUP by `persons`.`id`
";
$query = Person::hydrate(
DB::select( $sql )
);

How to add brackets around WHERE conditions with Laravel query builder

I'm using the Laravel query builder to dynamically filter data based on a user's filter selections:
$query = DB::table('readings');
foreach ($selections as $selection) {
$query->orWhere('id', $selection);
}
$query->whereBetween('date', array($from, $to));
$query->groupBy('id');
When I examine the SQL, I get something like this:
select count(*) as `count` from `readings` where `id` = 1 or id` = 2 and `date` between "2013-09-01" and "2013-09-31" group by `id`;
But what I need is something like this (with brackets around the or statements):
select count(*) as `count` from `readings` where (`id` = 1 or id` = 2) and `date` between "2013-09-01" and "2013-09-31" group by `id`;
How do I add brackets around WHERE conditions with Laravel query builder?
Very useful, I use this:
->where(function ($query) use ($texto){
$query->where('UPPER(V_CODIGO)', 'LIKE', '%'.Str::upper($texto).'%')
->orWhere('UPPER(V_NOMBRE)', 'LIKE', '%'.Str::upper($texto).'%');
});
I couldn't find this in documentation, whereNested was what I was looking for. Hope it helps anybody.
$q->whereNested(function($q) use ($nameSearch) {
$q->where('name', 'LIKE', "%{$nameSearch}%");
$q->orWhere('surname', 'LIKE', "%{$nameSearch}%");
});
Note: This is on Laravel 4.2
Solved this myself by using a closure, as described in Parameter Grouping in the query builder documentation.
$query = DB::table('readings');
$this->builder->orWhere(function($query) use ($selections)
{
foreach ($selections as $selection) {
$query->orWhere('id', $selection);
}
});
$query->whereBetween('date', array($from, $to));
$query->groupBy('id');
Sometimes you may need to group several "where" clauses within parentheses in order to achieve your query's desired logical grouping. In fact, you should generally always group calls to the orWhere method in parentheses in order to avoid unexpected query behavior. To accomplish this, you may pass a closure to the where method:
$users = DB::table('users')
->where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();
As you can see, passing a closure into the where method instructs the query builder to begin a constraint group. The closure will receive a query builder instance which you can use to set the constraints that should be contained within the parenthesis group. The example above will produce the following SQL:
select * from users where name = 'John' and (votes > 100 or title = 'Admin')
You can use WHERE IN here for the same effect:
$query = DB::table('readings');
$query->whereIn('id', $selection)
$query->whereBetween('date', array($from, $to));
$query->groupBy('id');

How to run raw SQL Query with Zend Framework 2

Is there a way to execute a SQL String as a query in Zend Framework 2?
I have a string like that:
$sql = "SELECT * FROM testTable WHERE myColumn = 5"
now I want to execute this string directly.
Just pass the sql string to your db adapter like this:
$resultSet = $adapter->query($sql, \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
And if you want to pass parameters:
$sql = "SELECT * FROM testTable WHERE myColumn = ?";
$resultSet = $adapter->query($sql, array(5));
EDIT: Please note that the query method does not always returns a resultset. When its a resultset producing query(SELECT) it returns a \Zend\Db\ResultSet\ResultSet otherwise(INSERT, UPDATE, DELETE, ...) it will return a \Zend\Db\Adapter\Driver\ResultInterface.
And when you leave the second Parameter empty you will get a \Zend\Db\Adapter\Driver\StatementInterface which you can execute.
use Zend\Db\Sql\Sql;
use Zend\Db\Adapter\Adapter;
$dbAdapterConfig = array(
'driver' => 'Mysqli',
'database' => 'dbname',
'username' => 'dbusername',
'password' => 'dbuserpassword'
);
$dbAdapter = new Adapter($dbAdapterConfig);
$sql = new Sql($dbAdapter);
$select = $sql->select();
$select->from('testTable');
$select->where(array('myColumn' => 5));
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
S. docu: Zend\Db → Zend\Db\Sql
If you are using tableGateway, you can run your raw SQL query using this statement,
$this->tableGateway->getAdapter()->driver->getConnection()->execute($sql);
where $sql pertains to your raw query. This can be useful for queries that do not have native ZF2 counterpart like TRUNCATE / INSERT SELECT statements.
If you have EntityManager $em on your hands, you can do something like this:
$select = $em->getConnection()->executeQuery("
SELECT a.id, a.title, a.announcement, asvc.service_id, COUNT(*) AS cnt,
GROUP_CONCAT(asvc.service_id SEPARATOR \", \") AS svc_ids
FROM article AS a
JOIN articles_services AS asvc ON asvc.article_id = a.id
WHERE
asvc.service_id IN (
SELECT tsvc.service_id
FROM tender AS t
JOIN tenders_services AS tsvc ON tsvc.tender_id = t.id
WHERE t.id = :tenderId
)
GROUP BY a.id
ORDER BY cnt DESC, a.id DESC
LIMIT :articlesCount
", [
'articlesCount' => 5,
'tenderId' => $tenderId,
], [
'articlesCount' => \PDO::PARAM_INT,
]);
$result = $select->fetchAll(); // <-- here are array of wanted rows
I think this way to execute complex queries is best for Zend. But may be I'm not very smart in Zend still. Will glad to see if it helps to someone.