CakePHP 3 DISTINCT has no effect on generated query - cakephp

CakePHP 3.5.13
$query = $Substances->find()->select(['id']);
debug($query->sql());
Produces:
'SELECT Substances.id AS `Substances__id` FROM substances Substances'
Trying to do the MySQL equivalent of DISTINCT() by changing the query to:
$query = $Substances->find()->select(['id'])->distinct(['id']);
Results in exactly the same query string as without ->distinct():
'SELECT Substances.id AS `Substances__id` FROM substances Substances'
Why is this? According to the documentation, that's how you write a DISTINCT() query using Cake's ORM.

Related

Django model based on an SQL table-valued function using MyModel.objects.raw()

If it's relevant I'm using Django with Django Rest Framework, django-mssql-backend and pyodbc
I am building some read only models of a legacy database using fairly complex queries and Django's MyModel.objects.raw() functionality. Initially I was executing the query as a Select query which was working well, however I received a request to try and do the same thing but with a table-valued function from within the database.
Executing this:
MyModel.objects.raw(select * from dbo.f_mytablefunction)
Gives the error: Invalid object name 'myapp_mymodel'.
Looking deeper into the local variables at time of error it looks like this SQL is generated:
'SELECT [myapp_mymodel].[Field1], '
'[myapp_mymodel].[Field2] FROM '
'[myapp_mymodel] WHERE '
'[myapp_mymodel].[Field1] = %s'
The model itself is mapped properly to the query as executing the equivalent:
MyModel.objects.raw(select * from dbo.mytable)
Returns data as expected, and dbo.f_mytablefunction is defined as:
CREATE FUNCTION dbo.f_mytablefunction
(
#param1 = NULL etc etc
)
RETURNS TABLE
AS
RETURN
(
SELECT
field1, field2 etc etc
FROM
dbo.mytable
)
If anyone has any explanation as to why these two modes of operation are treated substantially differently then I would be very pleased to find out.
Guess you've figured this out by now (see docs):
MyModel.objects.raw('select * from dbo.f_mytablefunction(%s)', [1])
If you'd like to map your table valued function to a model, this gist has a quite thorough approach, though no license is mentioned.
Once you've pointed your model 'objects' to the new TableFunctionManager and added the 'function_args' OrderedDict (see tests in gist), you can query it as follows:
MyModel.objects.all().table_function(param1=1)
For anyone wondering about use cases for table valued functions, try searching for 'your_db_vendor tvf'.

Reduce arrays where values are equals

It's a simple question I think, but i can't handle this.
If you see the image, here is my DB with multiple Usernames and "instances_id". If I var_dump this I have 11 arrays (and that's normal).
Is there a way to reduce arrays where "instance_id" is equal?
So that I have the first array containing "Alessio,Giorgio", the second one "Alessio,Giovanni" etc.
I use laravel... I hope you can help me
You could use combination of GROUP BY with GROUP_CONCAT to retrieve directly from db:
$result = DB
::table('example')
->selectRaw('instance_id, GROUP_CONCAT(Username)')
->groupBy('instance_id')
->get();
Or via laravel collection:
$result = DB::table('example')->get();
$result = $result
->groupBy('instance_id')
->map(function($group){
$data = $group->first();
$data->Username = $group->pluck('Username')->implode(',');
return $data;
})
->values();
Try..
SELECT * FROM tableName GROUP BY fieldName;
The following query will select all fields along with distinct zip field.
There are two ways.
1)select *
from table
group by field1
2) select distinct on field1 *
from table

sqlsrv does not support named parameters to queries

I'm using PHP7 (with Droctrine 2.5.13) on Ubuntu 16.04 x64.
I'm trying to do a prepared statment to a Microsoft SQL database using a named variable like so:
$sql = 'SELECT DISTINCT
"PRODUCT"."NUMBER"
FROM
"PRODDB"."PRODUCT"
WHERE
"PRODUCT"."NUMBER" LIKE :productNumber
ORDER BY
"PRODUCT"."NUMBER" DESC';
$query = $this->db->prepare($sql);
$query ->bindParam(':productNumber' , $ofSearch);
$status = $query->execute();
$result = $query->fetchAll();
But SQL tell me that I need to use question mask instead of the named parameter
Error : sqlsrv does not support named parameters to queries, use question mark (?)
If I replace the named variable by a question mark it work fine.
The example below work fine:
$sql = 'SELECT DISTINCT
"PRODUCT"."NUMBER"
FROM
"PRODDB"."PRODUCT"
WHERE
"PRODUCT"."NUMBER" LIKE ?
ORDER BY
"PRODUCT"."NUMBER" DESC';
$query = $this->db->prepare($sql);
$query ->bindParam(1 , $ofSearch);
$status = $query->execute();
$result = $query->fetchAll();
Using question mark is a terrible way to do prepared statement as when you have very complex query with over 20 parameters it become a nightmare to maintain.
Do you have any idea if there is a solution to this problem or at least a workaround?

CAKEPHP 3 : Select * and sum() in one statement

I am trying to fetch result from database table with SELECT * and SUM() function.
The sql query is :
SELECT * ,SUM(msg_send) AS msg_send FROM msg_campaigns
Now how to write this query in cakephp3.
I am trying this :
$this->loadModel('MsgCampaigns');
$SmsDetails = $this->MsgCampaigns->find('all',[
'conditions'=>['YEAR(date_time)'=>date('Y')],
'fields'=>['msg_send'=>'SUM(msg_send)','msg_failed'=>'SUM(msg_failed)']
]);
But I do not know how to use SELECT * . Please help
Check the CakePHP Query Builder on how to use SQL functions and how to select all fields.
$query = $this->MsgCampaigns->find();
$query
->select([
'sum_msg_send' => $query->func()->sum('msg_send'),
'sum_msg_failed' => $query->func()->sum('msg_failed')
])
// passing the table instance to the `select` function, selects all fields
->select($this->MsgCampaigns);
$query->execute();

PostgreSQL query not working in Yii2

I want to execute query in my yii2 application. I'm using PostgreSQl. There is a table called list inside the user schema. If I try to build any query it returns 1. My code is here:
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list"
')->execute();
Please show me my mistake in the query above.
This is not related to the DB type in Yii2 if you want the result of a single value you should use queryScalar() instead of execute()
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list" ')->queryScalar();

Resources