Laravel 4 select distinct - php

I have a table with email addresses and want to make a disctinct select (dont have duplicate email addresses in my result). The column with the email address is called 'mail_address'
I have tried:
ContactMail::distinct('mail_address')->get();
And:
ContactMail::distinct()->get();
But both give me just the complete table, also the rows where I have the same email address.
The complete query that I am building looks like this:
$list = ContactMail::where('campaign_id', '=', $campaign_id)
->where('mail_address', '!=', '')
->distinct('mail_address')
->get();
What am I doing wrong? I did not find good docu for distinct.

Using distinct in ORM is a bit pointless - in the end every model is distinct.
So I suggest, that you don't load the models, but single field that you need:
$list = ContactMail::where('campaign_id', '=', $campaign_id)
->where('mail_address', '!=', '')
->distinct()
->lists('email_address');
This way you get an array of distinct emails, instead of full models, or incomplete models when using select and get

$list = ContactMail::where('campaign_id', '=', $campaign_id)
->where('mail_address', '!=', '')
->select('mail_address')
->distinct()
->get();

Related

Using multi where queries Laravel relationships

I have two tables (Table1, Table2).
I want to print the sum of the records whose properties match Table1 in Table2 while listing the Table1 table.
My two tables contain very large records, performance is important to me.
// Model -> relationships
public function cars()
{
return $this->hasMany('App\Models\Table2', 'list_id', 'list_id');
}
// Controller
$table1 = Table1::with('cars' => function($query){
$query->where('table2.color','=', 'table1.color')
$query->where('table2.year','=', 'table1.year')
}])
->get();
I'm adding the sample database pictures:
Thank you.
First, add below use statement to the top of your controller:
use DB;
Now, If you only want to get the records amount, you can do this:
$amount = DB::table('table1')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
But if you want to get the list of the table1 records, you can change the query a bit like below:
$records = DB::table('table1')
->select('table1.*')
->join('table2', function($join){
$join->on('table1.color', '=', 'table2.color');
$join->on('table1.year', '=', 'table2.year');
})->count();
Please follow Laravel's official guide on this topic:
https://laravel.com/docs/8.x/queries#advanced-join-clauses
Use join to merge the two tables read more about join here https://www.w3schools.com/sql/sql_join.asp

Laravel 5.1: handle joins with same column names

I'm trying to fetch following things from the database:
user name
user avatar_name
user avatar_filetype
complete conversation_messages
with the following query:
static public function getConversation($id)
{
$conversation = DB::table('conversation_messages')
->where('belongsTo', $id)
->join('users', 'conversation_messages.sender', '=', 'users.id')
->join('user_avatars', 'conversation_messages.sender', '=', 'user_avatars.id')
->select('users.name', 'conversation_messages.*', 'user_avatars.name', 'user_avatars.filetype')
->get();
return $conversation;
}
It works fine so far, but the avatar's column name is 'name' like the column name from the 'users' table.
So if I'm using this query the to get the output via $conversation->name, the avatar.name overwrites the users.name
Is there a way to rename the query output like the mysql "as" feature at laravel 5.1?
For example:
$conversation->avatarName
$conversation->userName
Meh okay.. i've found a simple solution here
->select('users.name as userName', 'conversation_messages.*', 'user_avatars.name as avatarName', 'user_avatars.filetype')
As you can mention I've added the requested "as-Feature" next to the table.columnName
Take a look at this example of trying to join three tables staffs, customers and bookings(pivot table).
$bookings = \DB::table('bookings')
->join('staffs', 'staffs.id' , '=', 'bookings.staff_id')
->join('customers', 'customers.id' , '=', 'bookings.customer_id')
->select('bookings.id', 'bookings.start_time', 'bookings.end_time', 'bookings.service', 'staffs.name as Staff-Name', 'customers.name as Customer-Name')
->orderBy('customers.name', 'desc')
->get();
return view('booking.index')
->with('bookings', $bookings);
I had the following problem, simplified example:
$result = Donation::join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
$result is a collection of Donation models. BUT CAREFUL:
both tables, have a 'created_at' column. Now which created_at is displayed when doing $result->created_at ? i don't know. It seems that eloquent is doing an implicit select * when doing a join, returning models Donation but with additional attributes. created_at seems random. So what I really wanted, is a return of all Donation models of the user with email hello#papabello.com
solution is this:
$result = Donation::select('donation.*')->join('user', 'user.id', '=', 'donation.user_id')->where('user.email', 'hello#papabello.com')->first();
Yeah, simply rename the column on either table and it should work.
Also what you can do is, rename the user.name column to anything, also rename sender column of conversation_messages to id and perform a natural join.

Laravel Query Builder - sum() method issue

I'm new to laravel and I have some issues with the query builder.
The query I would like to build is this one:
SELECT SUM(transactions.amount)
FROM transactions
JOIN categories
ON transactions.category_id == categories.id
WHERE categories.kind == "1"
I tried building this but it isn't working and I can't figure out where I am wrong.
$purchases = DB::table('transactions')->sum('transactions.amount')
->join('categories', 'transactions.category_id', '=', 'categories.id')
->where('categories.kind', '=', 1)
->select('transactions.amount')
->get();
I would like to get all the transactions that have the attribute "kind" equal to 1 and save it in a variable.
Here's the db structure:
transactions(id, name, amount, category_id)
categories(id, name, kind)
You don't need to use select() or get() when using the aggregate method as sum:
$purchases = DB::table('transactions')
->join('categories', 'transactions.category_id', '=', 'categories.id')
->where('categories.kind', '=', 1)
->sum('transactions.amount');
Read more: http://laravel.com/docs/5.0/queries#aggregates
If one needs to select SUM of a column along with a normal selection of other columns, you can sum select that column using DB::raw method:
DB::table('table_name')
->select('column_str_1', 'column_str_2', DB::raw('SUM(column_int_1) AS sum_of_1'))
->get();
You can get some of any column in Laravel query builder/Eloquent as below.
$data=Model::where('user_id','=',$id)->sum('movement');
return $data;
You may add any condition to your record.
Thanks
MyModel::where('user_id', $_some_id)->sum('amount')

Selecting row from table in laravel

I've two different database tables entries and backers.
I wanted to select the rows from entries by comparing the email address of the user->email and the email in the backers table. Then I need to take the crowd_fund_id of those matching rows to get the rows from the table entries.
I tried the following queries and didn't work:
$donations = DB::table('entries')
->join(
'backers',
function($join, $user){
$join->on(
'entries.crowd_id',
'backers.crowd_fund_id'
)
->where(
'backers.email',
$user->email
);
}
)
->get();
and
$donations = Entries::where(
'crowd_id',
Backers::where('email', $user->email)->pluck('crowd_fund_id')
)->get();
What will be the best way to get the row from entries ?
Your syntax is a little off...
$donations = DB::table('entries')
->join('backers', function($join) use ($user)
{
$join->on('entries.crowd_id', '=', 'backers.crowd_fund_id')
->where('backers.email', '=', $user->email);
})->get();
The second query gives one result because you are using pluck(). If you just want a list (array) of crowd_fund_id, use ->lists('crowd_fund_id') rather than ->pluck().
it would be simpler if you do this
Banker::join('entries','entries.crowd_id','=','bankers.crowd_fund_id')
->where('bankers.email',$user->email)->get();

Laravel 4 select column from another table in subquery

I am attempting to do the equivalent of this:
select p.id, p.title, b.brand,
(select big from images where images.product_id = p.id order by id asc limit 1) as image
from products p
inner join brands b on b.id = p.brand_id
Here is where I am at now, but it of course doesn't work:
public function getProducts($brand)
{
// the fields we want back
$fields = array('p.id', 'p.title', 'p.msrp', 'b.brand', 'p.image');
// if logged in add more fields
if(Auth::check())
{
array_push($fields, 'p.price_dealer');
}
$products = DB::table('products as p')
->join('brands as b', 'b.id', '=', 'p.brand_id')
->select(DB::raw('(select big from images i order by id asc limit 1) AS image'), 'i.id', '=', 'p.id')
->where('b.active', '=', 1)
->where('p.display', '=', 1)
->where('b.brand', '=', $brand)
->select($fields)
->get();
return Response::json(array('products' => $products));
}
I don't really see anything in the docs on how to do this, and I can't seem to piece it together from other posts.
In "regular" SQL, the subquery is treated AS a column, but I am not sure how to string that together here. Thanks for any help on this.
I strongly recommend you to use Eloquent, instead of pure SQL. It's one of the most beautful things in Laravel. Two models and relations and it's done! If you need to use pure SQL like that, put it all in DB::raw. It's easier, simpler and (ironically) less messy!
With the models, you could use relations between the two tables (represented by the models itself) and say (so far I understood) that Brands belongs to Products, and Images belongs to Product. Take a look at Eloquent's documentation on Laravel. Probably will be more clearly.
Once the relations are done, you can only say that you wanna get
$product = Product::where(function ($query) use ($brand){
$brand_id = Brand::where('brand', '=', $brand)->first()->id;
$query->where('brand_id', '=', $brand_id);
})
->image()
->get();
That and a better look at Eloquent's documentation should help you to do the job.
P.S.: I didn't test the code before send it and wrote it by head, but i think it works.

Categories