converting SQL into KNEX multiple conditions - mysql

I'm trying to convert my SQL into KNEX. what I have so far is:
SQL:
SELECT name from students where attendance = "90" AND timestamp between "2020-05-14" AND "2020-05-18";
my attempt to convert to KNEX:
const from = req.query.from;
const to = req.query.to
router.get('/students/attendance?from=&to='
req.db.from('students').select("*").where('attendance', '=', req.params.attendance).andWhere('timestamp', 'between', [from, to])
MYSQL code works and returns what I want but I'm assuming my syntax is wrong with the Knex. Push in the right direction please

Where between is documented here https://knexjs.org/#Builder-whereBetween
await req.db
.from('students')
.select("*")
.where('attendance', req.params.attendance)
.whereBetween('timestamp', [from, to])
Also you can use .toSQL() to inspect the built query query.

Related

laravel to MySql query not displaying accurate results

i tried to do this insert and update another table with the sum of the data and the new values, but im getting wrong results
please help me convert this laravel to sql.
thanks in advance:
laravel:
$viaturas = Viaturas::firstWhere('matricula', $viaverde->matricula);
$viaturas->total_viaverde = $viaverde->custo + $viaturas->total_viaverde;
$viaturas->update();
sql not doing right as follows:
UPDATE `viaturas`
INNER JOIN `viaverde` ON `viaverde`.`matricula`=`viaturas`.`matricula`
SET `viaturas`.`total_viaverde` = (SELECT SUM(`viaverde`.`custo`));
The correct method is save()
$viaturas = Viaturas::firstWhere('matricula', $viaverde->matricula);
$viaturas->total_viaverde = $viaverde->custo + $viaturas->total_viaverde;
$viaturas->save();
If you use update(), you have two options
From the Model object
$viaturas = Viaturas::firstWhere('matricula', $viaverde->matricula);
# update this $viatura model
$viaturas->update(['total_viaverde' => $viaverde->custo + $viaturas->total_viaverde]);
From the Query Builder
# update every Viatura where matricula = $viaverde->matricula
Viaturas::query()
->where('matricula', $viaverde->matricula)
->update(['total_viaverde' => $viaverde->custo + $viaturas->total_viaverde]);
To run that specific SQL query from the query builder, I think this should do it
Viatura::query()
->join('viaverde', 'viaverde.matricula', 'viaturas.matricula')
->update(['viaturas.total_viaverde' => DB::raw('select sum(`viaverde`.`custo`)')]);

How to select a column in knex getting the result in UPPERCASE?

I am trying to select from a table the column name, but would like to get it all caps, using UPPER.
I would like to to it without using Knex raw SQL, but it doesn't work.
That's what I am trying to do:
const usersJornadasComites = await Database.table('tb_usuario_jornada')
.where('tb_usuario_jornada.jornada_id', lastJornad.id)
.where('tb_usuario_jornada.comite_id', params.id)
.where('tb_usuario_jornada.ativo', 1)
.select(
'tb_usuario.id',
'UPPER(tb_usuario.nome)',
'tb_usuario.email',
'tb_usuario.celular',
'tb_usuario.dt_nascimento',
'tb_usuario_jornada.criado_em',
'tb_usuario.id',
'tb_usuario_jornada.usuario_id'
)
.leftJoin(
'tb_usuario',
'tb_usuario_jornada.usuario_id',
'tb_usuario.id'
)
It gives me an error saying that UPPER(tb_usuario.nome) is not a valid column name.
Any ideas?
Many thanks,
Gines
just to inform if somebody else has the same issue.
The solution I used was to instead of using ORM syntax, I used the knex.raw select and it worked properly.
U can try to UPPER(tb_usuario.nome) as nome

Dynamyc queries in knex

I am trying to implement unions that can dynamically take query strings or builder as parameters. See the code below:
function dynamicUnion(queryString||builder){
baseQuery.union(function () {
//I want to use query string or querybuilder here instead.
this.select('*').from('users').whereNull('first_name');
})
}
In the place of the line: this.select('*').from('users').whereNull('first_name'), I would like to implement something like: this.raw(queryString||builder) or any working alternative though I've not come across .raw() method when working with this keyword in that block.
I am implementing it this way since the select queries that are to be used in the union will will vary and it's efficient if passed dynamically.
Sounds like a bug in knex that this.raw is not working in this case. Here is one way to pass raw query to union:
const Knex = require('knex');
const knex = Knex({
client: 'mysql',
});
knex('foo').union(knex.raw('foo bar')).toSQL();
// outputs "select * from `foo` union foo bar"
https://runkit.com/embed/10boda0lt1it

Cannot get MYSQL to query JSON column correctly in Laravel

I am trying to query a JSON column in MYSQL using Laravel. I cannot get it to pick up records when I know there should be.
This is my select statement if I try it directly in MySQL after extracting from Laravel:
select `resources`.*, `users`.* from `resources` inner join `users` on `resources`.`user_id` = `users`.`id` where `status_id` = 3 and `resources`.`languages`->'$.""$"'.`name"` = English
I tried cleaning it up a bit according to the MySQL documentation:
select `resources`.*, `users`.* from `resources` inner join `users` on `resources`.`user_id` = `users`.`id` where `status_id` = 3 and `resources`.`languages`->"$.name" = "English"
My actual Laravel code is this:
$query = DB::table('resources')
->join('users', 'resources.user_id', '=', 'users.id')
->select('resources.*', 'users.*')
->where('status_id', '=', 3);
if (isset($languagesearch)) $query=$query->where('resources.languages->"$.name"', $languagesearch);
if (isset($formatssearch)) $query=$query->whereRaw('JSON_EXTRACT(resources.formats, "$.name") = "'.$formatssearch.'"');
$resources = $query->get();
$resources = json_decode( json_encode($resources), true);
You I have two JSON columns and I have tried them both using two different methods but still no luck. It does set or unset the value correctly, it is just the where clause that is not working.
EDIT: The JSON Column format is: [{"name": "English"}, {"name": "German"}, {"name": "Portuguese"}]
My MySQL version is 5.7.18
The Laravel query builder just uses plain -> operators. It will convert it to the correct syntax on the back end. Your where clause should just look like:
if (isset($languagesearch)) {
$query = $query->where('resources.languages->name', $languagesearch);
}
if (isset($formatssearch)) {
$query = $query->where('resources.formats->name', $formatssearch);
}
You can read more about json where clauses in the documentation here.
This, of course, assumes you're using a supported version of MySQL (at least 5.7.9).
Edit
Because you're trying to search for a certain value inside of a json array, you will need to use the JSON_CONTAINS() function. You may want to look at the documentation for json search functions here.
With the current way your json is structured, you would need something like:
if (isset($languagesearch)) {
$query = $query->whereRaw('JSON_CONTAINS(resources.languages, \'{"name": "'.$languagesearch.'"}\')');
}

Laravel Sum column database Eloquent

Trying to get the sum of a int field in one of my table should be pretty easy, unfortunately it is not as I'm getting different result whether I use Laravel, MySQL or Excel.
Laravel 5.4 gives me 20506:
Table::sum('field_name');
MySQL gives me 1830:
Select sum(field_name) from table;
And the data from the Excel sheet before importing it into the database:
Sum gives me 145689
Any idea? I tried to cast to integer before doing the sum but it doesn't work.
All the numbers are pretty big but don't contain comma or dot.
Examples of values I have to sum: (contain sometimes empty cells)
17906774
99630157
28581131
159551532
20312892
668928885
$query = YourModel::query();
$query->withCount([
'activity AS yoursum' => function ($query) {
$query->select(DB::raw("SUM(amount_total) as paidsum"))->where('status', 'paid');
}
]);
You can use laravel aggregate function SUM as :
$result = DB::table('table_name')
->select(DB::raw('SUM(field_name) as total_field_name'))
->get();
For more details you can follow:
https://laravel.com/docs/5.4/queries
Thanks
Try with
$result = DB::table(tablename)
->selectRaw('sum(column)')
->get();
If it still gives you wrong result, maybe wait for someone to give you a better answer. This is all I could think of.