Alias name in having clause in laravel 5.1 - laravel-5

I'm using a function which is using alias name in "HAVING" clause and I'm getting an error,
"Unknown column 'orderStatusWithoutOpen' in 'having clause'".
Here is my code:
public static function getEquipmentPaginated($conditions = false, $id = false,$orderby='equipment_no',$order='asc',$filter=false)
{
$equipment = Equipment::select('checklist.*');
$equipment->leftjoin('checklist','equipment_id','=','equipment.id');
$equipment->addSelect('equipment.*', DB::Raw("(SELECT count(ordre.status = 001) FROM ordre LEFT JOIN checklist ON checklist.ordre_id=ordre.id WHERE checklist.equipment_id=equipment.id and ordre.status = 001 order by ordre.start_date desc limit 1) AS orderStatusWithoutOpen"));
$equipment->groupBy('equipment.id');
$start = date('Y-m-d');
$end = date('Y-m-d', strtotime('+15days'));
if($filter == '1' && $filter != "") {
$equipment->having('orderStatusWithoutOpen', "<", $filter);
}
if($filter == $start) {
$equipment->whereBetween('certificate.valid_date', [$start, $end]);
}
if($id) {
$equipment->where('equipment.customer_id', '=', $id);
}
return $equipment->paginate(10);
}
Can anyone please tell me what mistake I'm making here.
Thanks in advance.

Actually I corrected this myself. The query is working good and problem is with the pagination. So what I did is, I return the result within the if condition where I'm using 'HAVING' clause. Like Mentioned below:
if($filter == '1' && $filter != "")
{
$equipment->having('orderStatusWithoutOpen', "<", $filter);
return $equipment->get();
}

You have to bring the value in select query on which you want to order the result.
For example if equipment_fabricat.fabricat_name THEN
get that value in select(equipment_fabricat.fabricat_name) before applying order by

Related

How can I convert native PHP7 into query eloquent Laravel?

I'm migrating from php 7 to laravel and am having trouble completing the query. how to solve data query like the example below
$year = date('Y');
$month = date('m');
select id, tglupload,
substring(CONVERT(varchar,tglupload,106),4,2) date,
COUNT(1) as Totalemployeall
from [MS_SK]
where substring(CONVERT(varchar,tglupload,106),4,2) = $month
and substring(CONVERT(varchar,tglupload,106),7,4) = $year
AND (status_allow <> 'NOTALLOW' OR status_allow is null)
GROUP BY rollup(id, tglupload)
order by id ASC
Unfortunately you have to use a raw query for that. But you can make your query nicer using the Laravel's scope function.
For example in your model (the model related with the table [MS_SK]) you can add the following 2 scope functions:
class YourModel extends Model {
public function scopeFiltrateTglUpload($query, int $month=null, int $year=null)
{
$year = $year ?? date('Y');
$month = $month ?? date('m');
return $query->where(\DB::raw("substring(CONVERT(varchar,tglupload,106),4,2)", "=", $month))
->where(\DB::raw("substring(CONVERT(varchar,tglupload,106),7,4)", "=", $year));
}
public function scopeTheStatusIsNullOrNotAllowed($query)
{
return $query->where(function($subQuery) {
$subQuery->where('status_allow', '<>', 'NOTALLOW')
->orWhereNull('status_allow');
});
}
}
Then you can use them as per below:
$result = YourModel::selectRaw('
`id`, `tglupload`,
substring(CONVERT(varchar,tglupload,106),4,2) `date`,
COUNT(1) as `Totalemployeall`
')
->filtrateTglUpload()
->theStatusIsNullOrNotAllowed()
->groupBy(\Db::raw('rollup(id, tglupload)'))
->orderBy('id')
->get();
Please note that this is just an example to give you an idea. Then you should make it work :) Please tell me in the comment if you need any help.

Column 'department_id' in where clause is ambiguous

I got error on my page like the title above.
I am trying to export an Excel with the Laravel Excel extension.
Here is my code:
public function query()
{
$test = Leave::query()
->join('departments as dep', 'leaves.department_id', '=', 'dep.id')
->join('employees as emp', 'leaves.employee_id', '=', 'emp.id')
->join('users as emplUser', 'emp.user_id', '=', 'emplUser.id')
->join('users as apprUser', 'leaves.approved_by_id', '=', 'apprUser.id')
->select('leaves.id',
'dep.name',
'emplUser.first_name',
'leaves.start',
'leaves.end',
'leaves.type',
'leaves.reason',
'leaves.approved',
'leaves.approved_on',
'apprUser.first_name',
'leaves.approved_comment',
'leaves.created_at',
'leaves.updated_at',
)
->whereDate('leaves.start','>=', $this->periodStart)
->whereDate('leaves.end', '<=', $this->periodEnd);
return $test;
}
and here is the SQL from the error message:
select
`leaves`.`id`,
`dep`.`name`,
`emplUser`.`first_name`,
`leaves`.`start`,
`leaves`.`end`,
`leaves`.`type`,
`leaves`.`reason`,
`leaves`.`approved`,
`leaves`.`approved_on`,
`apprUser`.`first_name`,
`leaves`.`approved_comment`,
`leaves`.`created_at`,
`leaves`.`updated_at`
from `leaves`
inner join `departments` as `dep` on `leaves`.`department_id` = `dep`.`id`
inner join `employees` as `emp` on `leaves`.`employee_id` = `emp`.`id`
inner join `users` as `emplUser` on `emp`.`user_id` = `emplUser`.`id`
inner join `users` as `apprUser` on `leaves`.`approved_by_id` = `apprUser`.`id`
where date(`leaves`.`start`) >= 2021-07-04 and date(`leaves`.`end`) <= 2021-12-31
and (`department_id` = 2 or `department_id` is null)
order by `leaves`.`id` asc limit 1000 offset 0
I have notice that it says:
where ... and (`department_id` = 2 or `department_id` is null)
But I have never specified department_id, just like the start and end date. I think it needs like leaves.department_id, but how can I do that when I have never write it from the first time?
Update with more code:
This is from the LeaveController:
public function export()
{
$now = Carbon::now()->startOfWeek(Carbon::SUNDAY);
$start = $now;
$end = $now->copy()->endOfYear();
$period = new Period($start, $end);
return (new LeavesExport)->forPeriod($period->start, $period->end)->download('download.xlsx');
}
This is some of the code from Leave, that I found that contains department in some way:
use App\Traits\HasDepartment;
* App\Leave
* #property int $department_id
* #property-read \App\Department $department
* #method static \Illuminate\Database\Eloquent\Builder|\App\Leave whereDepartmentId( $value )
class Leave extends Model
{
use HasDepartment, ...
public static function getTypes()
{
try {
return LeaveType::where('department_id', current_department()->id)->pluck('name', 'id');
} catch (\Exception $e) {
error_log('User id: ' . auth()->user()->id . ' does not have an assigned Department');
return collect([]);
}
}
}
The error in your WHERE clause is ambiguous means that the system is not able to indentify department_id because there are more than 1 column with that name. You need to specify it first.
return LeaveType::where('leaves.department_id', current_department()->id)->pluck('name', 'id');

where clause is ambiguous on a query

I built a search module to get results form different params ! it"s work but when i when to export the result in csv i'm getting problems with my join table. for exemple when i search with a catg_licence_id i get an exception like :
SQLSTATE[23000]: Integrity constraint violation: 1052 Column
'catg_licence_id' in where clause is ambiguous
here my controller to get the result and generate the file with the join tables to get the value from the other tables and not simple ids . hope someone could help me. thanks a lot in advance :)
public function exportLicencesExcelWithParam(Request $request){
$type_licence = Type_licence::pluck('lb_type' , 'id');
$activite = ActiviteLicencie::pluck('lb_activite' , 'id');
$catg_licence = CatgLicence::pluck('lb_catg_lic' , 'id');
$structure = Structure::select('num_structure', 'nom_structure' , 'id')
->get()
->mapWithKeys(function($i) {
return [$i->id => $i->num_structure.' - '.$i->nom_structure];
});
$query = Licencies::query();
$filters = [
'type_licence' => 'type_licence_id',
'activite_licencie' => 'activite_licencie_id',
'assurance' => 'lb_assurance_etat',
'catg_licence' => 'catg_licence_id',
'structure' => 'structure_id',
];
foreach ($filters as $key => $column) {
if ($request->has($key)) {
$query->where($column, $request->{$key});
}
}
$action = Input::get('action', 'none');
if($action =='send'){
//HERE I WANT TO GENERATE THE CSV FILE BUT I NEED TO GET THE JOIN TABLES TO DISPLAY THE RESULT
$licencies = $query->join('activite_licencie', 'activite_licencie.id', '=', 'licencies.activite_licencie_id')
->join('saisons', 'saisons.id', '=', 'licencies.saison_id')
->join('pays', 'pays.id', '=', 'licencies.pays_naissance_id')
->join('type_licence', 'type_licence.id', '=', 'licencies.type_licence_id')
->join('structures', 'structures.id', '=', 'licencies.structure_id')
->join('civilite', 'civilite.id', '=', 'licencies.civilite_id')
->join('catg_licence', 'catg_licence.id', '=', 'licencies.catg_licence_id')
->select('num_licence', 'civilite.lb_civilite', 'lb_nom', 'lb_prenom', 'dt_naissance', 'pays.fr as pays', 'activite_licencie.lb_activite', 'catg_licence.lb_catg_lic', 'type_licence.lb_type', 'saisons.lb_saison', 'lb_surclassement', 'structures.nom_structure', 'structures.num_structure', 'lb_assurance', 'cd_dept_naissance', 'lb_ville_naissance', 'lb_adresse', 'tel_fix_licencie', 'tel_port_licencie', 'adresse_email')
->get();
$licencies->map(function ($licencie) {
$licencie['dt_naissance'] = \Carbon\Carbon::parse($licencie['dt_naissance'])->format('d/m/Y');
$licencie['lb_nom'] = strtoupper($licencie['lb_nom']);
$licencie['lb_prenom'] = ucfirst(strtolower($licencie['lb_prenom']));
if ($licencie['num_structure'] == 662883) {
$licencie['lb_activite'] = 'Super League';
} elseif ($licencie['num_structure'] == 311197) {
$licencie['lb_activite'] = 'ChampionShip';
} else {
//do nothing
}
if ($licencie['lb_activite'] == 'Tricolore LER' or $licencie['lb_activite'] == 'Tricolore - Autres Divisions') {
$licencie['lb_activite'] = 'Tricolore';
}
if ($licencie['lb_type'] == 'Membre') {
$licencie['lb_catg_lic'] = '';
}
return $licencie;
});
$date = Carbon::now('Europe/Paris')->format('d-m-Y h:m:s');
$file = Excel::create('' . $date . '', function ($excel) use ($licencies) {
$excel->sheet('Excel', function ($sheet) use ($licencies) {
$sheet->fromArray($licencies);
});
})->string('csv');
Storage::disk('local')->put('licencies_export_'.$date.'.csv' , $file);
return back()->with('status', "Fichier Exporté");
}else{
}
return view('export/licences' , compact('type_licence' , 'structure' , 'structures' , 'licencies' , 'activite' , 'catg_licence'));
}
here the full exception:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column
'type_licence_id' in where clause is ambiguous (SQL: select
num_licence, civilite.lb_civilite, lb_nom, lb_prenom,
dt_naissance, pays.fr as pays,
activite_licencie.lb_activite, catg_licence.lb_catg_lic,
type_licence.lb_type, saisons.lb_saison, lb_surclassement,
structures.nom_structure, structures.num_structure,
lb_assurance, cd_dept_naissance, lb_ville_naissance,
lb_adresse, tel_fix_licencie, tel_port_licencie, adresse_email
from licencies inner join activite_licencie on
activite_licencie.id = licencies.activite_licencie_id inner
join saisons on saisons.id = licencies.saison_id inner join
pays on pays.id = licencies.pays_naissance_id inner join
type_licence on type_licence.id = licencies.type_licence_id
inner join structures on structures.id =
licencies.structure_id inner join civilite on civilite.id =
licencies.civilite_id inner join catg_licence on
catg_licence.id = licencies.catg_licence_id where
type_licence_id = 4 and catg_licence_id = 1)
When it says it's ambiguous, what it means is that the mysql is joining tables and that specific field (catg_licence_id) is found on another table. So what happens is when you're joining something to this field, he doesn't know what table to join with. A solution would be to place the table name before, something like #user3154557 just said
->join('tablename', 'tablename.field', 'othertablename.field')
You're not joining the 'licencies' table anywhere.
->join('catg_licence', 'catg_licence.id', '=', 'licencies.catg_licence_id')
That line is your problem.
You might also get the same error in your select. It's better to put the table.property in the select rather than the property when you're joining a bunch of tables.

OctoberCMS - Model query with relation manyToMany

Once again i'm asking some help from the community...
Scenario:
I have two tables with one pivot table (something like posts and tags to give some context):
table 1 (Evento):
-id
-....
table 2 (Etiquetas):
-id
-etiqueta
pivot table (Eventos_Etiquetas):
-evento_id (pk)
-etiqueta_id (pk)
The relations are set as:
public $belongsToMany = [
'eventos' => ['JML\Gkb\Models\Evento', 'table' => 'jml_gkb_eventos_etiquetas']
];
and
public $belongsToMany = [
'etiquetas' => ['JML\Gkb\Models\Etiqueta', 'table' => 'jml_gkb_eventos_etiquetas']
];
Now, what i want to achieve:
-get all events that have any individual tag without regarding the order of input (or).
-get all events that have all tags without regarding the order of input (and).
As you can imagine i'm strugling with this as i'm new to October/Laravel query builder (and not so to sql).
What i've done so far:
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
if (Session::get('modo') == 0){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->where('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
if (Session::get('modo') == 1){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->orWhere('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
}
The user input is passed by $temp variable and it's splited to words to the $pesquisa array variable. 'modo' defines if the user pretend a search by AND (0) or by OR (1). Based on that choice a query is built to try to get the results using $palavra variable as any word of $pesquisa.
The result of this:
In modo == 0, i only can get the events of one tag of user input, if it have more than one word (any letter that don't exist on first word) don't get any result.
In modo == 1 it gets all events.
In both cases i don't get any event that don't have any tag (etiqueta) - correct behaviour.
I've tried some other ways but with no avail... This one looks to me the most logical of the tries... Can someone point me on the correct direction ?
TIA
JL
After some tries i have half of the problem solved. The part where i want to get any "Evento" that has any of the "Etiqueta" on user input not regarding the order of them is working fine finally.
Resume bellow
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
/***** NOT WORKING YET *****/
if (Session::get('modo') == 0){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->where('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
/****** THIS IS WORKING FINE ! *******/
if (Session::get('modo') == 1){
if ( count ($pesquisa) > 0 && !($temp == null)){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa");
})->orderBy('id', 'DESC')->paginate(25);
} else {
Evento::paginate(25);
}
}
}
The first parte is fighting, but i will get there. :)
TIA
JL
[EDIT]
Problem solved... The resulting snipet of code working so far with the tests i've done is bellow:
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
$contagem = count($pesquisa);
if (Session::get('modo') == 0){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having(DB::raw("COUNT('etiqueta_id')"), '>=', $contagem );
})->paginate(25);
} else {
$this['records'] = Evento::paginate(25);
}
}
if (Session::get('modo') == 1){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa");
})->paginate(25);
} else {
$this['records'] = Evento::paginate(25);
}
}
}
JL

Retrieving correct data from the database using Laravel Eloquent

I am trying to retrieve data from the database however I am not getting right results. It looks like my "If" statements are not working properly as I am getting some data from the "$sale->whereRaw" query which is at the beginning of foreach. What I am doing wrong?
I am working with Laravel 4.2.
Controller:
$matches = Match::where('PeopleID', '=', $id);
$sales = Sale::leftJoin('property', 'sales.property_id', '=', 'property.property_id')
->where('Status', '=', 'ForSale');
foreach($matches as $match)
{
$county = $match->county;
$sales->whereRaw("match (`county`) against (?)", array($county));
if($match->tenureFh == '1')
{
$sales->where('Tenure','=','FH');
if($match->minPrice != '0')
{
$sales->where('PriceFreehold', '>=' , $match->minPrice);
}
if($match->maxPrice != '0')
{
$sales->where('PriceFreehold', '<=', $match->maxPrice);
}
}
if($match->tenureLh == '1')
{
$sales->where('Tenure', '=', 'LH');
if($match->minPrice != '0')
{
$sales->where('PriceLeasehold', '>=' , $match->minPrice);
}
if($match->maxPrice != '0')
{
$sales->where('PriceLeasehold', '<=', $match->maxPrice);
}
}
}
$results = $sales->orderBy('sales.updated_at', 'asc')->get();
Match Model
public function people()
{
return $this->belongsTo('People', 'PeopleID', 'PeopleID');
}
public function sale()
{
return $this->hasMany('Sale');
}
Sale Model
public function match()
{
return $this->belongsTo('Match');
}
People Model
public function matches()
{
return $this->hasMany('Match', 'PeopleID', 'PeopleID');
}
public function sale()
{
return $this->hasMany('Sale');
}
#uptade
Currently I am getting the results from this statement:
$sales->whereRaw("match (`county`) against (?)", array($county));
Which is good however I need to filter the results further and this is where the "if" statements come in to place.
"Match" contains different searching credentials for each customer. If the candidate is looking for product with "Tenure: FH" In county "A" I need to display products with county "A" and which "Tenure" is "FH" (That is why I have made some those "if" statements). However those statements does not seem to work as I am getting ALL results for county "A" which "Tenure" is "FH" or other than "FH".
So the problem must be with those "Ifs" as they are not filtering the result further.
Imagine you have signed in with cars dealership website and you are looking for a red, 4 door car however the result you are getting is ALL 4 door cars but with all different colours (but you wanted a red one right?) - This is how it works at the moment.
I think you can do dd(DB::getQueryLog()); to see what query you get in the end.

Resources