Query Builder raw sub query is not working - sql

I'm having Problem running this code.It says:
Syntax error or access violation: 1064 You have an error in your SQL
syntax.
I don't know if this is coming form subquery.Is it correct to write subquery like this?
$result = DB::table('grievance_redress_info')
->select(
'complainer_name',
'phone',
'complaint_date',
'address',
'complaintSub.name_en',
'resolve_action_date',
DB::raw("(SELECT grievance_history.status
FROM grievance_history
WHERE grievance_history.grievance_id=grievance_redress_info.id
ORDER BY grievance_history.id DESC LIMIT 1) AS current_status")
)
->leftJoin("common_labels AS
complaintSub",'grievance_redress_info.complaint_subject_id','=','complaintSub.id')
->get();

I think you can do something like this
$grievance_redress_info = DB::table('grievance_redress_info')
->select(
'complainer_name',
'phone',
'complaint_date',
'address',
'complaintSub.name_en',
'complaintMeans.name_en',
'resolve_action_date');
$result = DB::table('grievance_history')
->leftJoinSub($grievance_redress_info, 'grievance_redress_info', function ($join) {
$join->on('grievance_history.grievance_id', '=', 'grievance_redress_info.id');
})->select('grievance_history.status')->get();
you can check the docs for more
I hope this works!

Related

How count by the first letters in Laravel Query Builder?

I want to make a count by the first letters... I have this column
I would like to count each OE rows and each GICS rows
I'm working with this query
$data4 = DB::table('incidencias')
->select(DB::raw('grupo_asig as grupo_asig'), DB::raw('count(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig')
->orderBy('number', 'desc')
->get();
Use CASE WHEN and count the field like OE and ASIG
$data4 = DB::table('incidencias')
->select(DB::raw("(CASE WHEN grupo_asig LIKE 'OE%' THEN 'OE'
WHEN grupo_asig LIKE 'GICS%' THEN 'GICS'
END) AS grupo_asig_type"),
DB::raw('COUNT(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig_type')
->orderBy('number', 'desc')
->get();
You should try to use the [LIKE][1] function then and add it to your query:
->where('grupo_asig', 'like', 'OE%')
->where('grupo_asig', 'like', 'GICS%')
Edit:
I tried a lot around and came to this solution and made a SQL fiddle: http://sqlfiddle.com/#!9/06a39b/8
Does it help you?
You could use Collections. No real need to change your query much.
$data4 = DB::table('incidencias')
->select('grupo_asig')
->selectRaw('count(*) as number'))
->whereNotIn('grupo_asig', [''])
->groupBy('grupo_asig')
// ->orderBy('number', 'desc') Unless you use this array somewhere, it's not needed.
->get();
use Illuminate\Support\Str;
...
// php >= 7.4.0
$oe_count = $data4->filter(fn($data) => Str::startsWith($data->grupo, 'OE '))->count();
$gigs_count = $data4->filter(fn($data) => Str::startsWith($data->grupo, 'GIGS '))->count();
// php < 7.4.0
$oe_count = $data4->filter(function ($data) {
return Str::startsWith($data->grupo, 'OE ');
})->count();
$gigs_count = $data4->filter(function ($data) {
return Str::startsWith($data->grupo, 'GIGS ');
})->count();
Starting with Laravel 6, you can also use cursor() instead of get() in your query to return a LazyCollection. It's faster for this scenario.
I would suggest using a query for that:
refer to this answer
SELECT
LEFT(grupo_asig, 1) AS first_letter,
COUNT(*) AS total
FROM incidencias
GROUP BY first_letter

Laravel using a case statement

I'm trying to retrieve all messages of a conversation and display it's status (read or unread). With a CASE I try to read the message.read property (boolean) and process it to a string.
$messages = DB::table('conversation_message')
->select(
'messages.id as message_id',
'messages.created_at as send_at',
'messages.user_id as from_id',
'messages.body as body',
'conversations.id as conversation',
DB::raw('(CASE WHEN messages.read = 1 THEN read ELSE unread END) AS status')
)
->leftjoin('messages', 'messages.id', '=', 'conversation_message.message_id')
->leftjoin('conversations', 'conversations.id', '=', 'conversation_message.conversation_id')
->orderBy('send_at', 'asc')
->get();
Without the CASE, the query works fine but with the case I recieve a Syntax error or access violation: 1064 near 'read.
Solved it by placing both the outcomes read and unread in double quotes.
$messages = DB::table('conversation_message')
->select(
'messages.id as message_id',
'messages.created_at as send_at',
'messages.user_id as from_id',
'messages.body as body',
'conversations.id as conversation',
DB::raw('(CASE WHEN messages.read = 1 THEN "read" ELSE "unread" END) AS status')
)
->leftjoin('messages', 'messages.id', '=', 'conversation_message.message_id')
->leftjoin('conversations', 'conversations.id', '=', 'conversation_message.conversation_id')
->orderBy('send_at', 'asc')
->get();
Now I can use the status directly as a css class!

Laravel eloquent where with relationship

I am stuck on transforming this SQL query to an eloquent query in Laravel. The SQL query works (tested in Sequel) but I cannot write it in eloquent ...
SELECT faqs.question FROM faqs
JOIN categories c ON c.id = faqs.category_id
WHERE c.subsite = 'sport'
This is what I have tried so far, but it returns all the questions, (ignoring the subsite filter).
$cat = Faq::with(['category' => function($query) use ($subsite) {
$query->where('subsite', $subsite);
}])->get();
Thanks for the help
Try this
$cat = Faq::query();
if (isset($subsite) && !empty($subsite) {
$query->whereHas('category', function ($query) use ($subsite) {
$query->where('subsite', $subsite);
});
}
$query->with('category')->get();
as per you core sql query, here is your laravel query.
$data = DB::table('faqs')
->join('categories', 'categories.id', '=', 'faqs.category_id')
->select('faqs.question')
->where('categories.subsite', '=', 'sport')
->get();
Hope this will help you!

Select sql code in Laravel

Following query returning six values
SELECT tbl_start FROM timetable inner join route ON tbl_rte_id = id WHERE rte_origin = "UL" and rte_destination = "HW" ORDER BY(tbl_start) DESC;
And my laravel code is returning only one value
$tables = Timetable::join('route', 'tbl_rte_id', '=', 'id')
->where('rte_origin', $origin, 'AND')
->where('rte_destination', $destination)
->orderBy('tbl_start', 'desc')
->get();
foreach ($tables as $table) {
$result[$table->id] = $table->tbl_start;
}
This laravel code is not similar or similar. Can anyone help me.
Change this part:
->where('rte_origin', $origin, 'AND')
// to:
->where('rte_origin', $origin)
It will know by default that it's AND operator
And if you want to provide this operator, then do this:
->where('rte_origin', '=', $origin, 'AND')
You may try something like this:
$tables = Timetable::join('route', 'tbl_rte_id', '=', 'timetable.id')
->where('rte_origin', $origin)
->where('rte_destination', $destination)
->orderBy('tbl_start', 'desc')
->get()->lists('tbl_start', 'id');
The $tables will contain an array of id => tbl_start pairs.
Add a listener in your routes.php
Event::listen('illuminate.query', function($sql){
var_dump($sql);
});
Then execute both queries and check if you have the same result

Codeigniter Joining Tables - Passing Parameters

I'm attempting to join two tables while using codeigniter. I've done this same SQL query writing regular SQL. When I attempt to do the same in codeigniter, I keep getting errors. I'm not quite sure what I'm doing wrong. What do you guys think I'm doing wrong?
My function in model_data.php
function getJoinInformation($year,$make,$model)
{
//$this->db->distinct();
// here is where I need to conduct averages but lets just work on extracting info.
// from the database and join tables.
$this->db->select('*');
$this->db->from('tbl_car_description');
$this->db->join('tbl_car_description', 'd.id = p.cardescription_id');
$this->db->where('d.year', $year);
$this->db->where('d.make', $make);
$this->db->where('d.model', $model);
$result = $this->db->get();
/*
$query = $this->db->get_where('tbl_car_description',
array(
'year' => $year,
'make' => $make,
'model' => $model
)
);
if($query->num_rows()) return $query->result();
return null;
*/
}
My error message
A Database Error Occurred
Error Number: 1066
Not unique table/alias: 'tbl_car_description'
SELECT * FROM (`tbl_car_description`) JOIN `tbl_car_description` ON `d`.`id` = `p`.`cardescription_id` WHERE `d`.`year` = '2006' AND `d`.`make` = 'Subaru' AND `d`.`model` = 'Baja'
Filename: C:\wamp\www\_states\system\database\DB_driver.php
Line Number: 330
Here is the code written in SQL and it's working great. I want to do the something in codeigniter but I'm confused as to how. Any help would be much appreciated. Thanks everyone.
$sql_2 = mysql_query("SELECT ROUND(AVG(p.value),1) AS AvgPrice, ROUND(AVG(p.mileage),1) AS AvgMileage
FROM tbl_car_description d, tbl_car_prices p
WHERE (d.id = p.cardescription_id)
AND (d.year = '".$year."')
AND (d.make = '".$make."')
AND (d.model = '".$model."')
AND (p.approve = '1')");
Your CI query references the same table twice, which I assume is a typo. However, you only need include your table alias with the table name in your Active Record call:
//$this->db->distinct();
$this->db->select('*');
$this->db->from('tbl_car_description d');
$this->db->join('tbl_car_prices p', 'd.id = p.cardescription_id');
$this->db->where('d.year', $year);
$this->db->where('d.make', $make);
$this->db->where('d.model', $model);
$result = $this->db->get();
Couple issues: You need to include your table aliases and your join should have the name of the second table ...
$this->db->from('tbl_car_description AS d');
$this->db->join('tbl_car_prices AS p', 'd.id = p.cardescription_id');