I am using a global search bar that accepts user input as strings. However, I want to emit special typing characters. Think of dots, commas, ETC. You can see my current database check below (since it is Ajax based):
public function scopeWhereName($query, $queryString) {
$query->where(function ($query) use ($queryString) {
$query->where(\DB::raw("REPLACE(name, ' ', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '.', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, ',', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '!', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '?', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, ':', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '-', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '#', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '#', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '&', '')"), 'LIKE', '%' . $queryString . '%')
->orWhere(\DB::raw("REPLACE(name, '/', '')"), 'LIKE', '%' . $queryString . '%');
});
}
My question, as stated in the title, is If it is possible that the queries above can be made into a better query, so it is performance lighter and easier to read.
You can simplify the query creation:
$chars = [' ', '.', ',', ...];
foreach($chars as $char) {
$query->orWhere(\DB::raw("REPLACE(name, '$char', '')"), 'LIKE', '%' . $queryString . '%')
}
If you do a lot of searching, you should maybe create a separate column that stores the name without special characters.
Related
with this code I implemented a search:
if ($request->keyword != "") {
$users = User::where('firstname', 'like', '%' . $request->keyword . '%')
->orWhere('lastname', 'like', '%' . $request->keyword . '%')
->orWhere('email', 'like', '%' . $request->keyword . '%')
->orderBy('lastname')
->whereJsonContains("out", Auth::user()->id)
->paginate($request->total);
} else {
$users = User::whereJsonContains("out", Auth::user()->id)->orderBy('lastname')->paginate($request->total);
}
Filtering for firstname, lastname and e-mail works fine, but the important where with "->whereJsonContains("out", Auth::user()->id)" not work. After typing "s" every User with "s" will be displayed in results.... what is wrong?
You ay try
if ($request->keyword != "") {
$users = User::query()
->where(function($query) use($request){
$query->where('firstname', 'like', '%' . $request->keyword . '%')
->orWhere('lastname', 'like', '%' . $request->keyword . '%')
->orWhere('email', 'like', '%' . $request->keyword . '%');
})
->whereJsonContains("out", Auth::user()->id)
->orderBy('lastname')
->paginate($request->total);
} else {
$users = User::whereJsonContains("out", Auth::user()->id)
->orderBy('lastname')
->paginate($request->total);
}
Query will return records where either the firstname, lastname or email contains anything like $request->keyword and the out column contains the currently logged in user's id.
Hello hope y'all doing well. I am trying to union three different tables that have a unique parent with Laravel. Below is the code:
$storage_rent = DB::table('storage_rents')
->select('order_id', 'start_date', 'end_of_free_charge', 'orders.order_type')
->distinct()
->join('orders', 'storage_rents.order_id', '=', 'orders.id')
->where('start_date', 'like', '%' . $q . '%')
->orWhere('end_of_free_charge', 'like', '%' . $q . '%');
$car_parkings = DB::table('car_parkings')
->select('order_id', 'start_date', 'end_of_free_charge', 'orders.order_type')
->distinct()
->join('orders', 'car_parkings.order_id', '=', 'orders.id')
->where('start_date', 'like', '%' . $q . '%')
->orWhere('end_of_free_charge', 'like', '%' . $q . '%');
return DB::table('shippings')
->select('order_id', 'port_of_destination', 'booking_number', 'orders.order_type')
->distinct()
->join('orders', 'shippings.order_id', '=', 'orders.id')
->where('port_of_destination', 'like', '%' . $q . '%')
->orWhere('container_number', 'like', '%' . $q . '%')
->orWhere('booking_number', 'like', '%' . $q . '%')
->union($storage_rent)
->union($car_parkings)
->get();
When I run that code, it works perfectly on Postman but if I deploy it on heroku postgresql, it gives me an error: SQLSTATE[42804]: Datatype mismatch: 7 ERROR: UNION types character varying and date cannot be matched. How can I resolve the issue, assuming that I wanted to query in each table. Result that it gives me on POSTMAN:
[
{
"order_id": 9,
"port_of_destination": "saint louis",
"booking_number": "",
"order_type": "Shipping"
},
{
"order_id": 11,
"port_of_destination": "2021-09-28",
"booking_number": "2021-10-28",
"order_type": "Storage rent"
},
{
"order_id": 10,
"port_of_destination": "2021-10-08",
"booking_number": "2021-10-15",
"order_type": "Car Parking"
}
]
im trying to write sql query in laravel:
select * from products where deleted=0 AND
(('name_ru','LIKE', '%' . $request->q_search . '%')
OR ('name_en','LIKE', '%' . $request->q_search . '%')
OR ('name_lv','LIKE', '%' . $request->q_search . '%'))
now i have:
$products = DB::table('product')
->select('id','name_lv', 'name_ru', 'name_en','price','desc')
->where('deleted',0)
->where('name_lv','LIKE', '%' . $request->q_search . '%')
->orWhere('name_ru','LIKE', '%' . $request->q_search . '%')
->orwhere('name_en','LIKE', '%' . $request->q_search . '%')
->distinct()
->orderBy('price', 'desc')
->paginate(10,['*'], 'found')
->onEachSide(6);
my problem is with condition deleted=0, my sql ignores it. Whats wrong? thanks for advice!
you can use where(function(){}) as you have where AND (.. OR ..)
$products = DB::table('product')
->select('id', 'name_lv', 'name_ru', 'name_en', 'price', 'desc')
->where(function ($q) use ($request) {
$q->where('name_lv', 'LIKE', '%' . $request->q_search . '%')
->orWhere('name_ru', 'LIKE', '%' . $request->q_search . '%')
->orwhere('name_en', 'LIKE', '%' . $request->q_search . '%');
})
->where('deleted', 0)
->distinct()
->orderBy('price', 'desc')
->paginate(10, ['*'], 'found')->onEachSide(6);
I have an equipment which has type, manufacturer , model etc and it has attributes which are in other tables. I have created a join condition to connect with attributes. Now, if i search for a keyword related to type, manufacturer or model, then it shows correct result. But , i also need to search by attribute. I don't know how to extend this search so that it can also fetch result on the basis of attributes which are in other tables. Another thing is if i right both manufacturer and attribute in search box in one time , then i need result of equipments which has both manufacturer and attribute. Please advise. Any help would be appreciated
Currently my code looks like this:
public function filterEquipementRecords(Request $request)
{
$equipements = Equipment::with('equip_status','equip_type','manufacturer', 'equip_model', 'equip_images', 'customer')
//These are join with different attribute tables
->selectRaw('equipment.*, Fuel.EQATTRPVAL_Value AS EQUIP_Fuel, Cab.EQATTRPVAL_Value AS EQUIP_Cab, Drive.EQATTRPVAL_Value AS EQUIP_Engine, PowerManu.EQATTRPVAL_Value AS EQUIP_Power, CabAttrib.EQATTR_YesNo AS EQUIP_CabYesNo')
// Fuel Type
->leftJoin('equipattributetypes as FuelType', function($join) {
$join->on('equipment.EQTYPE_ID', '=', 'FuelType.EQTYPE_ID')
->whereRaw("FuelType.EQATTRTYPE_Name = 'Fuel Type'");
})
->leftJoin('equipattributes as FuelAttrib', function($join) {
$join->on('equipment.EQUIP_ID', '=', 'FuelAttrib.EQUIP_ID')
->on('FuelType.EQATTRTYPE_ID', '=', 'FuelAttrib.EQATTRTYPE_ID');
})
->leftJoin('equipattributepickvalues as Fuel', function($join) {
$join->on('FuelAttrib.EQATTRPVAL_ID', '=', 'Fuel.EQATTRPVAL_ID');
})
// Cab
->leftJoin('equipattributetypes as CabType', function($join) {
$join->on('equipment.EQTYPE_ID', '=', 'CabType.EQTYPE_ID')
->whereRaw("CabType.EQATTRTYPE_Name = 'Cab'");
})
->leftJoin('equipattributes as CabAttrib', function($join) {
$join->on('equipment.EQUIP_ID', '=', 'CabAttrib.EQUIP_ID')
->on('CabType.EQATTRTYPE_ID', '=', 'CabAttrib.EQATTRTYPE_ID');
})
->leftJoin('equipattributepickvalues as Cab', function($join) {
$join->on('CabAttrib.EQATTRPVAL_ID', '=', 'Cab.EQATTRPVAL_ID');
})
// Drive
->leftJoin('equipattributetypes as DriveType', function($join) {
$join->on('equipment.EQTYPE_ID', '=', 'DriveType.EQTYPE_ID')
->whereRaw("DriveType.EQATTRTYPE_Name = 'Drive'");
})
->leftJoin('equipattributes as DriveAttrib', function($join) {
$join->on('equipment.EQUIP_ID', '=', 'DriveAttrib.EQUIP_ID')
->on('DriveType.EQATTRTYPE_ID', '=', 'DriveAttrib.EQATTRTYPE_ID');
})
->leftJoin('equipattributepickvalues as Drive', function($join) {
$join->on('DriveAttrib.EQATTRPVAL_ID', '=', 'Drive.EQATTRPVAL_ID');
})
//Power Manu
->leftJoin('equipattributetypes as PowerManuType', function($join) {
$join->on('equipment.EQTYPE_ID', '=', 'PowerManuType.EQTYPE_ID')
->whereRaw("PowerManuType.EQATTRTYPE_Name = 'Power Manu'");
})
->leftJoin('equipattributes as PowerManuAttrib', function($join) {
$join->on('equipment.EQUIP_ID', '=', 'PowerManuAttrib.EQUIP_ID')
->on('PowerManuType.EQATTRTYPE_ID', '=', 'PowerManuAttrib.EQATTRTYPE_ID');
})
->leftJoin('equipattributepickvalues as PowerManu', function($join) {
$join->on('PowerManuAttrib.EQATTRPVAL_ID', '=', 'PowerManu.EQATTRPVAL_ID');
})
// This is my query where i am searching on the basis of keyword, here i want to add attribute (which are there with joins) search also
->where(function ($query) use ($request) {
if($this->quick_search_enable){
if ($request->quick_search != "") {
$query->where('equipment.EQUIP_ID', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_AddedOn', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Year', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_VendorYear', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Cost', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Price', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_EmailPrice', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Size', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Hours', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_SerialNumber', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_VendorEquipNumber', 'like', '%' . $request->quick_search . '%')
->orWhere('EQUIP_Length', 'like', '%' . $request->quick_search . '%')
// These are relations in equipment model
$query->orWhereHas('manufacturer', function ($query) use ($term) {
$query->where('MANU_ShortName', 'like', '%' . $term . '%');
});
$query->orWhereHas('equip_type', function ($query) use ($term) {
$query->where('EQTYPE_Desc', 'like', '%' . $term . '%');
});
$query->orWhereHas('equip_model', function ($query) use ($term) {
$query->where('EQMODEL_ModelNumber', 'like', '%' . $term . '%');
});
$query->orWhereHas('equip_status', function ($query) use ($request) {
$query->where('EQSTATUS_Name', 'like', '%' . $request->quick_search . '%');
});
}
}
});
Trying to select entries from user input $query. I would like to search the first_name, last_name, address (etc) columns that has NULL on deleted_at. What I have done so far is:
$data = DB::table('users')
->where('first_name', 'LIKE', '%' . $query . '%')
->orWhere('last_name', 'LIKE', '%' . $query . '%')
->orWhere('address', 'LIKE', '%' . $query. '%')
->whereNull('deleted_at')
->get();
My goal is to search the above mentioned columns by the user's query and show any match it finds. Problem is, it also shows entries that are NOT NULL in the column deleted_at. I wish to only see results which are NULL at deleted_at. What may I have been doing wrong?
make use of parameter grouping
$data = DB::table('users')
->whereNull('deleted_at')
->where(function ($query) {
$query->where('first_name', 'LIKE', '%' . $query . '%')
->orWhere('last_name', 'LIKE', '%' . $query . '%')
->orWhere('address', 'LIKE', '%' . $query. '%');
})
->get();