How to convert Distinct Count SQL query into a Laravel Eloquent query - sql

I would like to convert this SQL query into a laravel eloquent query. So I can create
SELECT
count(distinct article_id) as assigned
FROM
actions
WHERE
action_id = 1 and
set_id = 1
I can translate the query into a raw request which works
DB::table('actions')->select(DB::raw('count(DISTINCT article_id) as assigned'))
->where('action_id', 1)
->where('set_id', 1)
->get();
But I would like to figure out how to do it something like this
$sets = Set::withCount(['actions as assigned' => function ($q) {
$q->distinct()
->select('article_id')
->where('action_id', '=', 1);
}])->get();
or this
$sets = Set::withCount(['actions as assigned' => function ($q) {
$q->distinct('article_id')
->where('action_id', '=', 1);
}])->get();
Eventually I would like to have my Set model contain a scoped method like this
public function scopeWithAssignedCount($query){
$query->withCount(['actions as assigned' => function ($q) {
$q->distinct('article_id')
->where('action_id', '=', 1);
}])
}
So I can add multiple counts to a single call in my controller
$sets = Set::withAssignedCount()
->withUnassignedCount()
->where('palm' => $face)
->get();
Edited per comments
I would like to use something like the below with distinct records.
public function scopeWithAssignedCount($query)
{
$query->withCount(['actions as assigned' => function ($q) {
$q->where('action_id', 1);
}]);
}

Check this query
$count = Set::select('article_id as assigned');
if(!empty($action_id)){
$count = $count->where('action_id', $action_id);
}
if(!empty($set_id)){
$count = $count->where('set_id', $set_id);
}
$count = $count->distinct('article_id')->count('article_id');

Related

Unable to insert id of user to another table laravel 8 livewire

I am unable to store user id of another user on my db. I have a messages table, where from_id,t_id and user_id are the foreign key of table users. I have models defined properly as well. The issue I am having is:
can't insert the user_id.
I can save everything else. when i do dd $this->id it shows the corret user id but when it comes to save them i can't.
I tried doing explode and it stopped showing those random values. it now gets the id however in below format: [{"id":3}]
: Invalid text representation: 7 ERROR: invalid input syntax for type bigint: "[{"id":3}]"
As you can see it's getting the user id when i get the values from authenticated user which is obvious.
My code :
public $messages, $sender;
public $users;
public $avatar;
protected $destination = '';
public $messageText;
public function mount($id)
{
$this->id = $id;
$this->avatar = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->distinct()->get();
$this->destination = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->first();
$this->users =
Message::latest()
->take(5)
->get()
->sortBy('id');
$this->messages = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.name', 'users.id', 'messages.message', 'messages.created_at')
->where('users.id', '=', $this->id)
->get();
// SELECT * FROM users AS u INNER JOIN messages AS m ON u.ID IN (m.senderID, m.recipientID) WHERE u.ID <> $userID GROUP BY u.ID ORDER BY m.sentAt DESC
}
public function render()
{
// $name = explode(' ', $this->avatar);
// dd($name);
return view(
'livewire.show',
[
'avatar' => $this->avatar,
'messages' => $this->messages,
'users' => $this->users,
]
)->layout('layouts.app');
}
public function sendMessage()
{
$name = explode(' ', $this->avatar);
// $this->validate(['messageText' => "required"]);
$message = new Message();
$message->from_id = Auth::user()->id;
$message->user_id = Auth::user()->id;
$message->to_id = $name[0]; // [{"id":3}]
$message->message = $this->messageText;
// dd($message);
$message->save();
$this->reset('messageText');
}
Error Message:

I want to use a variable in a WHERE clause in a SQL query, getting no results with this, also no errors

if I remove the 'column' parameter from the function and hard code a column name in the where clause this query works.
static async findByColumn(column, searchTerm) {
const term = `%${searchTerm}%`;
const { rows } = await pool.query(
`SELECT * FROM characters
WHERE $1
ILIKE $2`,
[column, term]
);
if(!rows[0]) return null;
else return rows.map(character => new Character(character));
}

Laravel 8 removing qoute on the sql

Hi i just wanna know if what i did wrong
this my function
public function fetchJobs(Request $request){
$id = (int)$request->input("id");
$jobs = DB::table('job')
->select('job.*')
->where('job.status', '=', 0)
->Where('application.applicant','=' ,null)
->leftJoin('application', function($join) use ($id)
{
$join->on('application.job', '=', 'job.id');
$join->on('application.applicant','=',$id);
})
->toSql();
return $jobs;
}
this is the result
select `job`.* from `job`
left join `application` on `application`.`job` = `job`.`id` and `application`.`applicant` = `39`
where `job`.`status` = 0 and `application`.`applicant` is null
the error of is that 39 has qoutes is there a way to remove the qoute?
i solved this by adding DB:raw()
public function fetchJobs(Request $request){
$id = (int)$request->input("id");
$jobs = DB::table('job')
->select('job.*')
->where('job.status', '=', 0)
->Where('application.applicant','=' ,null)
->leftJoin('application', function($join) use ($id)
{
$join->on('application.job', '=', 'job.id');
$join->on('application.applicant','=',DB::raw($id));
})
->get();
return $jobs;
}

Laravel: Conditional Eloquent query (Today, Month & Year)

I have many queries that I must repeat, since they depend on the choice of a filter obtained through a Select (Today, Month & Year), which shows the corresponding information in the ranges specified above: Current Day, Current Month and Year Current.
Here is the code:
if ($filterDashboardMerchant == 'month'){
// Total Revenue || Month
$totalRevenue = AffiliateOrder::join('affiliates', 'affiliates.id', '=', 'affiliates_orders.affiliate_id')
->whereMonth('order_date', Carbon::now()->month)
->select(DB::raw('sum(total) as orders_total'))
->where('affiliates.merchant_id', $merchant->merchant_id)
->get();
}
else{
if($filterDashboardMerchant == 'year'){
// Total Revenue || Year
$totalRevenue = AffiliateOrder::join('affiliates', 'affiliates.id', '=', 'affiliates_orders.affiliate_id')
->whereYear('order_date', Carbon::now()->year)
->select(DB::raw('sum(total) as orders_total'))
->where('affiliates.merchant_id', $merchant->merchant_id)
->get();
else{
// Total Revenue || Today
$totalRevenue = AffiliateOrder::join('affiliates', 'affiliates.id', '=', 'affiliates_orders.affiliate_id')
->whereDay('order_date', Carbon::now()->day)
->select(DB::raw('sum(total) as orders_total'))
->where('affiliates.merchant_id', $merchant->merchant_id)
->get();
}
}
Given that all the query code is the same and only 3 of the conditions are different within them:
->whereMonth('order_date', Carbon::now()->month)
->whereYear('order_date', Carbon::now()->year)
->whereDay('order_date', Carbon::now()->day)
How could only that condition change in the same code snippet, dependent on the choice in the Select that filters to them ?
It would be of great help to me, as this is just less than 5% of what I have developed and it would save me a lot of code.
Laravel has a when() query method, that only executes a given callback if a condition is true. Documentation.
AffiliateOrder::join('affiliates', 'affiliates.id', '=', 'affiliates_orders.affiliate_id')
->when($filterDashboardMerchant === 'day', function ($query) {
$query->whereDay('order_date', Carbon::now()->day);
})
->when($filterDashboardMerchant === 'month', function ($query) {
$query->whereMonth('order_date', Carbon::now()->month);
})
->when($filterDashboardMerchant === 'year', function ($query) {
$query->whereYear('order_date', Carbon::now()->year);
})
->select(DB::raw('sum(total) as orders_total'))
->where('affiliates.merchant_id', $merchant->merchant_id)
->get();
For a more clean approach scopes can be used, add the scope in your AffiliateOrder.php class.
public function scopeFilterAffiliates($query, $filter) {
$query->join('affiliates', 'affiliates.id', '=', 'affiliates_orders.affiliate_id')
->when($filter === 'day', function ($query) {
$query->whereDay('order_date', Carbon::now()->day);
})
->when($filter === 'month', function ($query) {
$query->whereMonth('order_date', Carbon::now()->month);
})
->when($filter === 'year', function ($query) {
$query->whereYear('order_date', Carbon::now()->year);
})
->select(DB::raw('sum(total) as orders_total'))
->where('affiliates.merchant_id', $merchant->merchant_id);
}
Now you can use the scope like so.
AffiliateOrder::filterAffiliates($filterDashboardMerchant)
->get();

codeigniter pagination for a query

So far found plenty of help to get the pagination working for a get(table) command.
What I need is to pick only few of the entries from a couple of linked tables based on a sql where statement.
I guess the query command is the one to use but in this case how do I do the pagination since that command does not take extra parameters such $config['per_page']
Thanks for the help
Without any more info to go on I think that what you're looking for is something like the following.
public function pagination_example($account_id)
{
$params = $this->uri->ruri_to_assoc(3, array('page'));
$where = array(
'account_id' => $account_id,
'active' => 1
);
$limit = array(
'limit' => 10,
'offset' => (!empty($params['page'])) ? $params['page'] : 0
);
$this->load->model('pagination_model');
$data['my_data'] = $this->pagination_model->get_my_data($where, $limit);
foreach($this->uri->segment_array() as $key => $segment)
{
if($segment == 'page')
{
$segment_id = $key + 1;
}
}
if(isset($segment_id))
{
$config['uri_segment'] = $segment_id;
}
else
{
$config['uri_segment'] = 0;
}
$config['base_url'] = 'http://'.$_SERVER['HTTP_HOST'].'/controller_name/method_name/whatever_your_other_parameters_are/page/';
$config['total_rows'] = $this->pagination_model->get_num_total_rows();// Make a method that will figure out the total number
$config['per_page'] = '10';
$this->load->library('pagination');
$this->pagination->initialize($config);
$data['pagination'] = $this->pagination->create_links();
$this->load->view('pagination_example_view', $data);
}
// pagination_model
public function get_my_data($where = array(), $limit = array())
{
$this->db
->select('whatever')
->from('wherever')
->where($where)
->limit($limit['limit'], $limit['offset']);
$query = $this->db->get();
if($query->num_rows() > 0)
{
$data = $query->result_array();
return $data;
}
return FALSE;
}
This should at least get you on the right track
If this isn't what you're asking I'd happy to help more if you can be a little more specific. How about some of your code.
The only other options that I can think of would be to either code a count in your select statement or not limit the query and use array_slice to select a portion of the returned array.