problem of syntax in where clause when 2 columns are equal? - laravel

I have a filter on a form before displaying a list.
If the filter 'filter_parisetat' = 2, i set the where clause like this :
$query = $query->where('gri_nb_matchs','gri_nb_matchs_pec');
I want to select all the rows of my Grille table where 'gri_nb_matchs' equals 'gri_nb_matchs_pec'
but it doesn't work..nothing is selected (and of course in my table I have 10 in each columns for these 2 fields
The other Where conditions in case 1 is equal to
$query = $query->where('gri_nb_matchs','>','gri_nb_matchs_pec');
I should retrieve 0 rows, but here I retrieve all the rows..
it works upside down...
In My table, the 2 fields are described like this :
11 gri_nb_matchs tinyint(3) UNSIGNED
12 gri_nb_matchs_pec tinyint(3) UNSIGNED
In MySql, whenI write the query, results are correct..
What went wrong ?
Thanks a lot
Thierry

In this statement:
$query = $query->where('gri_nb_matchs','>','gri_nb_matchs_pec');
It seems you are comparing the field gri_nb_matchs to the string value 'gri_nb_matchs_pec', not the column named gri_nb_matchs_pec. In order to achieve this you have to use a raw query as so:
$query = $query->where('gri_nb_matchs','>',DB::raw('gri_nb_matchs_pec'));
or
$query = $query->whereRaw('gri_nb_matchs > gri_nb_matchs_pec');

Related

Laravel query builder select all except specific column

I have 2 tables with the same columns except the second table have one more column, this column is foreign key of the first;
what i want is to make union query;but for union the column must the same; so i want to select all column except for the column distinct;
The easy way is to provide in select all the same column:
$a = Table1::select(['column1', 'column2', 'etc...']);
$b = Table2::select(['column1', 'column2', 'etc...']);
and go with $a->union($b)->get();
but if i have too much column, i end up with so much column to provide in the select function; so what i want is to provide in the query the column that i don't want to retrieve;
i can put protected $hidden in the second table model but for some reason i need this distinct column on some other query;
Get all columns name by Schema::getColumnListing($table);
And computes the intersection of arrays
array_intersect($columnsName1, $columnsName2);
I haven't done it with 2 tables but I am using collections and rejecting certain columns on a similar project:-
$row = Table1::firstOrFail();
$exclude=['column_1', 'column_2'];
return collect(array_keys($row->getAttributes()))
->reject(function ($name) use ($row, $exclude) {
return in_array($name, $row->getHidden())
|| in_array($name, $exclude);
}
);

Subtraction with aggregation using 2 tables

My Laravel query is not working properly. but MySQL query works fine
Laravel Query :
$data = DB::table(DB::raw('select (sum(case when type="credit" then amount else -amount end)) - (select sum(amount) from total) from report'))
Please refer mysql query in sqlfiidle : http://sqlfiddle.com/#!9/2d0343/9
Rather than try rewrite your MySQL query, let's simplify it and make it more eloquent.
Assuming $data is the overall balance and your model for the report table is called Report then the below should achieve what you are after:
$data = Report::where('type', 'credit')->sum('amount') - Report::where('type', 'debit')->sum('amount');
This will give you the sum of all your credits, minus the sum of all your debits.

How do I return last n records in the order of entry

From Laravel 4 and Eloquent ORM - How to select the last 5 rows of a table, but my question is a little different.
How do I return last N records ordered in the way they were created (ASC).
So for example the following records are inserted in order:
first
second
third
fourth
fifth
I want a query to return last 2 records
fourth
fifth
Laravel Offset
DB::table('users')->skip(<NUMBER Calulation>)->take(5)->get();
You can calculate N by getting the count of the current query and skipping $query->count() - 5 to get the last 5 records or whatever you wanted.
Ex
$query = User::all();
$count = ($query->count()) - 5;
$query = $query->skip($count)->get();
In pure SQL this is done by using a subquery. Something like this:
SELECT * FROM (
SELECT * FROM foo
ORDER BY created_at DES
LIMIT 2
) as sub
ORDER BY created_at ASC
So the limiting happens in the subquery and then in the main query the order by is reversed. Laravel doesn't really have native support for subqueries. However you can still do it:
$sub = DB::table('foo')->latest()->take(2);
$result = DB::table(DB::raw('(' . $sub->toSql() . ') as sub'))
->oldest()
->get();
And if you use Eloquent:
$sub = Foo::latest()->take(2);
$result = Foo::from(DB::raw('(' . $sub->toSql() . ') as sub'))
->oldest()
->get();
Note the latest and oldest just add an orderBy('created_at) with desc and asc respectively.

Subquery returning multiple rows during update

I have two tables T_SUBJECTS (subject_id, date_of_birth) and T_ADMISSIONS (visit_id, subject_id, date_of_admission, age). I want to update the age column with the age at time of admission. I wrote the update query and get the "single row sub-query returns more than one row". I understand the error but thought the where exists clause will solve the problem. Below is the query.
UPDATE
t_admissions
SET
t_admissions.age =
(
SELECT
TRUNC(months_between(t_admissions.date_of_admission,
t_subjects.date_of_birth)/12)
FROM
t_admissions,
t_subjects
WHERE
t_admissions.subject_id = t_subjects.subject_id
AND t_admissions.age = 0
AND t_admissions.date_of_admission IS NOT NULL
AND t_subjects.date_of_birth IS NOT NULL
)
WHERE
EXISTS
(
SELECT
1
FROM
t_admissions, t_subjects
WHERE
t_admissions.subject_id = t_subjects.subject_id
);
The problem is that your subquery in the SET clause returns multiple rows.
Having a WHERE clause will only filter which records get updated and nothing else.
In addition, your where clause will either always return true or always return false.
You should look into how to properly do a correlated update:
https://stackoverflow.com/a/7031405/477563
A correlated update is what I need as suggested in the above link. See answer below.
UPDATE
(
SELECT
t_admissions.visit_id,
t_admissions.date_of_admission doa,
t_admissions.age age,
t_subjects.date_of_birth dob
FROM
t_admissions,
t_subjects
WHERE
t_admissions.subject_id = t_subjects.subject_id
AND t_admissions.age = 0
AND t_admissions.date_of_admission IS NOT NULL
AND t_subjects.date_of_birth IS NOT NULL
)
SET
age = TRUNC(months_between(doa,dob)/12);

Select rows having 2 columns equal value in laravel Query builder

I want to write a query which selects rows where 2 attributes from 1 entity have equal value.
This would be an example of doing this in raw SQL:
Select * from users u where u.username = u.lastname
Does laravel have any methods that take 2 column names as parameters and return the matching results?
What you need is a DB::raw expression:
DB::table('users')
->where('username', '=', DB::raw('lastname'))
->get();
The only thing DB::raw actually does is to tell the query interpreter not to treat 'lastname' like any other string value but just interpolate it in the SQL as it is.
http://laravel.com/docs/queries#raw-expressions
In Laravel 5, there's now whereColumn for this, for cleaner code:
Users::whereColumn('username', 'lastname')->get();

Resources