How to compare value in two columns in FuelPHP - sql

I have problem when query table using FuelPHP 1.3's Model.
Entries table have three columns ('id', 'status', 'current', 'max' ).
$result = Model_Entry::query()
->where('status', 1)
->where('count_current', '>=', 'count_max');
I want to use 'where' method's third argument as column name, but it handled as value in generated query.
Example
SELECT * FROM `entries` AS `t0` WHERE `t0`.`status` = 1 AND `t0`.`count_current` >= 'count_max'
My Goal
SELECT * FROM `entries` AS `t0` WHERE `t0`.`status` = 1 AND `t0`.`count_current` >= `t0`.`count_max`
Any help would be appreciated.

To achieve what you want, you have to use DB::expr()
So, your code will be:
$result = Model_Entry::query()
->where('status', 1)
->where('count_current', '>=', DB::expr('count_max'));

Related

exists query does not return relevant result

I have a Laravel application with this Eloquent query:
$products = Product::where('name', 'LIKE', "%{$value}%")
->whereHas('categories', function($q) {
$q->where( 'slug', 'tonery-cartridge' );
})->with('manufacturer')
->with('sm_image')
->orderBy('created_at','DESC')
->take(10)
->get();
This code generates the sql command like:
select * from `products` where `name` LIKE '%can%'
and exists (
select * from `categories` inner join `category_product`
on `categories`.`id` = `category_product`.`category_id`
where `products`.`id` = `category_product`.`product_id`
and `slug` = 'tonery-cartridge'
)
order by `created_at` desc limit 10
I am sure there are products which name contains "can" string and which belongs to the category with slug "tonery-cartridge". Why this query returns an empty result? If I try to make inner join sql manually it works well as on the screenshot below:
I think that your queries are not equivalent. The SQL output from laravel does not join tables in it's FROM clause, but in your manually constructed SQL statement you do a lot of inner joins in your FROM clause and on the resulting table you perform your operations, which is not true for the former.
Try the following
DB::table('products')
->join('category_product', 'category_product.product_id', '=', 'products.id')
->join('categories', 'category_product.category_id', '=', 'categories.id')
->whereRaw('products.name LIKE %can% AND categories.slug = "tonery-cartridge"')
->select('products.name', 'categories.slug')
->orderBy('created_at','DESC')
->take(10)
->get()
If you want to avoid using whereRaw, you can try the following.
DB::table('products')
->join('category_product', 'category_product.product_id', '=', 'products.id')
->join('categories', 'category_product.category_id', '=', 'categories.id')
->where([
['products.name, 'LIKE', '%' . $value . '%'],
['categories.slug', '=', 'tonery-cartridge']])
->select('products.name', 'categories.slug')
->orderBy('created_at','DESC')
->take(10)
->get()
HTH
This could be one of the solutions
$category = Category::where( 'slug', 'tonery-cartridge' )->first();
$products = $category->products()
->where('name', 'LIKE', "%{$value}%")
->with('manufacturer')
->with('sm_image')
->latest()
->take(10)
->get();

Yii2: how to use subquery with ActiveRecord?

I want to create a find function to use then in a GridView widget My I don't know how to use a subquery.
This is the simple version of the PostgreSQL query that I have:
SELECT color
FROM cars
LEFT JOIN (
SELECT name
FROM companies
)
Here is what I a trying and doesn't work:
$query = Cars::find()
->select([
'color' => '
SELECT name // Problem here.
FROM companies // Problem here.
',
]);
Your expected query is not what you are trying to do. You can add a custom subquery as
$query = Cars::find()
->select([
'(SELECT name FROM companies) AS xxx'
]);
But if you want to add a field from joined table to the grid, then you should have a relation defined and then you can easily add such a column to your grid. See https://www.yiiframework.com/doc/guide/2.0/en/db-active-record#relational-data
You can use instance of ActiveQuery in leftJoin() method like this:
$subQuery = Companies::find()
->select('name', 'id'); //I've added ID to show how to write on condition
$query = Cars::find()
->select('color')
->leftJoin(
['alias' => $subQuery],
'alias.id = cars.company_id'
);
See documentation for more details about leftJoin() and join() methods.
$query = Cars::find()
->select(['cars.color','companies.name'])
->leftJoin('companies', 'cars.company_id = companies.id');

Number of rows of query - Yii

i want to get the number of rows returned by a query in Yii. This is my query :
$programsAlreadyExist = $connection->createCommand('
SELECT *
FROM `cat_programme`
WHERE `programme_code` = 513')
->queryAll();
The "COUNT" keyword should return a row containing the requested number. :-)
SELECT COUNT(*) FROM cat_programme WHERE programme_code = 513
Change the SELECT to:
SELECT count (*) FROM cat_programme WHERE programme_code = '513'
Thanks !!
You could also do if via the count() method
For ecample
$programsAlreadyExist = MyModel::find()
->where(['programme_code' => '513'])
->count();

cannot group with eloquent with PostreSQL

Here's my Eloquent query:
$visits = Visit::orderBy('date', 'desc')->groupBy('user_id')->get(['date', 'user_id']);
But posgreSQL is refusing the query, telling me:
SQLSTATE[42803]: Grouping error: 7 ERROR: column "visits.date" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select "date", "user_id" from "visits" group by...
the same stuff works on MySQL when I disable ONLY_FULLY_GROUP_BY
what can I do to make it work? It would be great if I didn't have to edit configs, just the code.
This selects the latest date for each user_id:
$sub = Visit::select('user_id', DB::raw('max("date") "date"'))->groupBy('user_id');
$sql = '(' . $sub->toSql() . ') as "sub"';
$visits = Visit::join(DB::raw($sql), function($join) {
$join->on('visits.user_id', 'sub.user_id')
->on('visits.date', 'sub.date');
})->orderBy('visits.date', 'desc')->get(['visits.date', 'visits.user_id']);
If there are multiple visits for a user_id and date combination, the query returns all of them. Removing the duplicates is possible, but makes the query more complex.
It's easier to remove them afterwards:
$visits = $visits->unique('user_id');
Using postgre sql you could use distinct on user_id and order your date column to pick latest date per user_id, In laravel you could raw expression
$visits = Visit::select(DB::raw('distinct on (user_id)'), 'date')
->orderBy('date', 'desc')
->get();
Demo

'OR' in NHibernate Lambda Extensions

How can I union two criteria with an OR statement?
For example I want to get Employee which has null in Birthday field OR value of this field is less than someDate. How should I rewrite this code:
var query = DetachedCriteria.For<Employee>()
.Add(SqlExpression.IsNull<Employee>(p => p.Birthday))
.Add<Employee>(emp => emp.Birthday.Value < someDate);
You need to use Disjunction()