Yii2 - find max based year in active record - php

I want to select maximum an field which is integer in my db.
So, First I try the orthodok's way :
SELECT max(a.nomor_surat) as max FROM request a
WHERE YEAR(a.tanggal_persetujuan) = YEAR(CURDATE())
Works. (In my case : max = 3)
Now, using AR,
Request::find()->select('max(nomor_surat) as max')->where(['YEAR(tanggal_persetujuan)' => 'YEAR(CURDATE())' ])->scalar();
I got max = 1,
How AR interpretatioin them correctly ?
Pleas Advice.
Thanks

Request::find()
->andWhere(['YEAR([[tanggal_persetujuan]])' => new \yii\db\Expression('YEAR(CURDATE())')])
->max('[[nomor_surat]]');

Related

Get latest value in the group of records

I have this records table which I save weight, age and other biometrics in it.
Now I want to fetch the latest value of every biometric for every day so I can draw a chart.
The piece of code I'm using to fetch data from db before processing it is like the following:
Records::where("user",$uid)->
where("type", "biometric" )-> // record type
where("fk", $bid )-> //biometric type
where("datetime","<" ,$range->max)->
where("datetime",">" ,$range->min)->
groupBy( "datee" )->
selectRaw(" max(amount) as 'damount' , max(unit) as 'unit' , date(datetime) as 'datee' ")->
orderBy("datee","desc")->
get();
// !! Should change max values with the latest record in the group !!
Which datee is date of the day.
Say some users add more than one weight biometrics in a day so unit and damount should be the unit and value of lastest record of that day.
What can I use instead of max() to achieve this?
Thanks in advance,
Hope this helps:
Records::where("user",$uid)
->where(["type" => "biometric", "fk" => $bid])
->whereBetween(DB::raw("DATE('datetime')"), array($range->max, $range->min))
->groupBy("datetime")->latest()->get();
Can you try this
Records::where("user",$uid)
->where("type", "biometric")
->where("fk", $bid)
->where("datetime","<" ,$range->max)
->where("datetime",">" ,$range->min)
->latest()
->groupBy('datetime')
->get();

Make unique ID using Laravel

I want to generate a unique id in Laravel.
EX: PO-12010001
PO = product,
12 = the month,
01 = the year,
0001 = ID of product.
I have tried googling and the answer is using UUID but could not understand.
Your ID will always be 4 digits at the end, so we can pluck those last four characters using substr(). When you increment that by one, it will lose its padding. So 0001+1=2. We therefor pad it back using str_pad() with a length of four.
$string = 'PO-12010001';
$id = substr($string, -4, 4);
$newID = $id+1;
$newID = str_pad($newID, 4, '0', STR_PAD_LEFT);
echo "PO-1201".$newID;
Live demo at https://3v4l.org/55RTL
Since it is not clear where the last 4 characters (ID of product) come from, there are 2 different outcomes based on their origin, I am assuming that "PO" is a constant in all your products:
1.If you're auto-generating the Product ID:
$id = "PO-".date('my') . substr(uniqid(), 9, 12);
date('my') will return a two-digits form of the current month and a two-digits form of the current year.
uniqid() returns a unique identifier based on the current time in microseconds, the identifier is usually a mix of letters and digits, and it is usually 13 characters long, so we use substr() to only return the last 4 characters of the string.
NOTE: we are using the last characters of uniqid() because they change every millisecond.
2.If you already have a Product ID:
$id = "PO-".date('my') . $product_id;
When like this situation first how you want to make your ID
Item Type
Month
Year
Product ID
Get product type in your controller
if Product = PO /
Service = SE
Create a New Date using PHP
$date2 = date('Y-m-d');
and get date substring with your requirement and get the last id of the product table and concat all the variable and use as Unique ID.
First, I dopn't know. So maybe it has a similar concept. But anyway, user defined+designed unique are most likely not unique.
My recommendation is to let the database create an unique id with the autoincrement feature. This is usually the only way to guarantee unique ideas in a multi tasking environment.
The, in an second step, you can create an human readable id and use it for displaying it at the suer interface. Such query can be something like:
update table set nice_id = concat("prefix-",main_id)
where main_id = $last_inserted_id
... or any other calculation based on counting the the number of same entries since beginning of month.
There are other solutions based on try to create an nice_id, insert it into the database, and if this fails, create the next one .. and loop until successful. But simple integers created by autoincrement are more performant on queries and for keys.
it's called Human code which can be unique identify beside an Id column in db table.
$idColumn = 1;
$dateCode = date('ym');
$newHumanCode = 'PO-'.$dateCode.substr('0000'.$idColumn, -4);
return $newHumanCode;
also you can use randome number instead of use $idColumn,
for example:
$idColumn = mt_rand();
You can use the Laravel ID generator.
First Install it:
composer require haruncpi/laravel-id-generator
Import the class in your controller.
use Haruncpi\LaravelIdGenerator\IdGenerator;
Now simply use it
$prefix = "PO-".date("my");
$id = IdGenerator::generate(['table' => 'your_table_name', 'length' => 11, 'prefix' =>$prefix]);
Output
PO-12010001
PO-12010002
PO-12010003
...

How To Get Maximum Of A Table Column In Yii2?

i want to get maximum of price from table laptop in yii2.
how can i do that?
i used below code
<?
Laptop::find()->max('price')
?>
but it seems not working :(
how can i access this data.
and in other type i coded before like below
<?
$min=Laptop::find()->select('min(price)');
?>
but it s not working again ..
how to add this query ??
Tecnically you don't need an Active Recordefor get the max or min result you could try using active Query
$max = (new \yii\db\Query())
->from('laptop_table')
->max('price');
echo $max;
If you have the error
Missing argument 1 for yii\db\Query::max()
is because you must pass the column name for calculate the max
anyway the code above is equivalent to
$max = Laptop::find()->max('price');
Like below :
echo $max_price = Laptop::find()->max("price");
Multi select and max price in the product table with model product:
$product = \common\models\Product::find()->where(['status'=> 1])->andWhere(['>','count',0])->max('price');

addBetweenCondition in YII

SO I want to find that if value x is exits between the values of 2 columns or not, For that i have run the query in phpmyadmin :
Normal Approch :-
SELECT * FROM `traits_versions` WHERE 16 BETWEEN `trait_value_lower` and `trait_value_upper` and `style_id` = 1
and it is giving me fine result.But when the same approach i want to find achieve in YII that it is not running and giving the sql error :
YII apprroch :-
$details = array();
$criteria = new CDbCriteria();
$criteria->addCondition('style_id='.$style_id);
$criteria->addCondition('version='.$version);
$criteria->addBetweenCondition($style_contribution,$this->trait_value_lower,$this->trait_value_upper);
$trait_details= $this->find($criteria);
When i debug the query in log than it shows in case of yii :
SELECT * FROM `traits_versions` `t` WHERE ((style_id=1) AND (version=1)) AND (16 BETWEEN NULL AND NULL) LIMIT 1
Why it is giving NULL value in query while i'm passing the name of the column in it.
So please guide me where i'm going wrong in yii.
Add compare condition like below
$criteria->compare('trait_value_lower', 16, false, '>');
$criteria->compare('trait_value_upper',16, false, '<');
instead of between condition
$criteria->addBetweenCondition($style_contribution,$this->trait_value_lower,$this->trait_value_upper);
because between condition will apply on one column as per Yii doc.
public static addBetweenCondition(string $column, string $valueStart, string $valueEnd, string $operator='AND')

Codeigniter update record

I have an update record that looks like this
$data_gallery = array(
'order' => $value
);
$this->db->where('order', $newOrder);
$this->db->update('gallery', $data_gallery);
I have say, 5 images I have reorderd. I have their old position and their new position.
But as I loop through they sometime overwrite each other.
Example:
5 images 1,2,3,4,5
I change the order 2,1,3,4,5
I update in the loop as it goes through the array of new order.
Update order = 2 where order = 1
Update order = 1 where order = 2
Obviously the second one never gets hit as order = 2 no longer exits.
I guess this more a logic question than anything else.
Any ideas how I can easily loop through and update without losing some of the data? I though maybe updating in a batch operation but didn't get very far with it.
Thanks in advance.
Use the image's ID in your WHERE clause:
$this->db->where('imageid', $imageid);
This will set the new order to each image without previously overwriting (and disappearing!) any information.
Check if you have any other fields to check for your criteria to match the exact records.
$data_gallery = array(
'order' => $value
);
$this->db->where('order', $newOrder);
//check if you have any other fields to match also image id, record id or any other ids to match
$this->db->where('second_id',$second_id);
$this->db->update('gallery', $data_gallery);

Categories