I have 2 tables which have been joined.
Table : affiliate
Fields : company,affid
+---------------------------+
|company|affid |
|Test1 | t1 ||Test1 | t2 |
Table : applicant
Fields : affid,commission
+---------------------------+
|affid |commission |
|t1 | 25 ||t2 | 30 |
Each company has for example 2 affid's.
So company name : Test1
Has affid : t1,t2
What i am trying to do is pull a table that shows the company name and its total commission.
+---------------------------+
|company|commission|
|Test1 | 55 |
This is what i have , what changes do i need to make ?
$data = DB::table('applicant')
->join('affiliate','applicant.affid','=','affiliate.affid')
->select(DB::raw('company,SUM(commission) as commission,'))
->groupBy('company')
->get();
Related
I have a table like below,I'm using vertica data base sql
| Name | Cust ID |
| | 1 |
| | 2 |
|Prem | 2 |
For cust ID 1 the name is blank, so it should display and N/A, for cust ID 2 we have 2 entries, which are 1 is blank and 2 is Prem, so blank should be ignored and should display Prem.
The final out put should be like this,
|Name | Cust ID |
|N/A |1 |
|Prem |2 |
The final output should be like this,
|Name | Cust ID |
|N/A |1 |
|Prem |2 |
This works if the non-empty name of the same cust-id is always the same in multiple rows. Note that I use the NULL value for non-existent data. An empty string and NULL are two different things, for me.
WITH
indata("name",custid) AS (
SELECT NULL , 1
UNION ALL SELECT NULL , 2
UNION ALL SELECT 'Prem', 2
)
SELECT
IFNULL(MAX("name"),'N/A') AS "name"
, custid
FROM indata
GROUP BY custid;
-- out Null display is "(null)".
-- out name | custid
-- out ------+--------
-- out N/A | 1
-- out Prem | 2
How to make a deep relationship with eloquent? I'm trying to display the data like this :
+------------------------------------+
| Main ID | Name | SN | Last Event |
|------------------------------------|
| 12 | James | j89 | RIGHT |
+------------------------------------+
The "Last Event" column is based on the latest data on "Tracks" table but the value "RIGHT" is relation between the "Tracks" table with "Events" table. So, in this table, the latest record in the tracks table is id of 9 with event_id of 12, the event_id of 12 in the Events table has name column that contained value RIGHT. That value that I want to grab it to display in front end. this is my table in database.
Main table
+---------------+
|id | name | sn |
|---------------|
|12 | James| j89|
+---------------+
Tracks table
+-------------------------------------+
|id | main_id | event_id | created_at |
|-------------------------------------|
| 5 | 10 | 10 | 2021-10-12 |
| 9 | 10 | 12 | 2021-11-20 |
+-------------------------------------+
Events
+----------+
|id | name |
|----------|
|10 | LEFT |
|12 | RIGHT|
+----------+
If I use has one relationship with latestOfMany() method, it didn't reach to the events table. How do I reach it to the Events table to grab the value in Events table through the latest data of Tracks table based on main_id? thanks!
you can use Eager Loading to load deep in your relation, if you setup your relation correctly:
class Main extends Model
{
public function latestTrack()
{
return $this->hasOne(Track::class,'main_id')->latestOfMany();
}
}
class Track extends Model
{
public function event()
{
return $this->belongsTo(Event::class,'event_id');
}
}
now you can get the structre you need:
$main=Main::with('latestTrack.event:id,name')->find(12);
I have 4 tables named: categories, products, blogs, companies.
+-----------+
| Category |
+----+------+
| id | name |
+----+------+
| 1 | Cat1 |
| 2 | Cat2 |
+----+------+
+-----------+
| Company |
+----+------+
| id | name |
+----+------+
| | |
+----+------+
+-------------------------+
| Product |
+----+-------------+------+
| id | category_id | name |
+----+-------------+------+
| 1 | 1 | P1 |
| 2 | 2 | P2 |
| 3 | 1 | P3 |
+----+-------------+------+
+---------------------------+
| Blog |
+----+------------+---------+
| id | product_id | heading |
+----+------------+---------+
| 1 | 1 | H1 |
| 2 | 2 | H3 |
| 3 | 3 | H4 |
+----+------------+---------+
Blog Model
public function product()
{
return $this->belongsTo(Product::class);
}
Product Model
public function company()
{
return $this->belongsTo(Company::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
Blog::with('product.category')
->where('status', 'Y')
->where('featured_position', 'Y')
->orderBy('id', 'DESC')
->get();
From the above tables the result will show 2 blogs namely blogs having id 1 and 3. But the above code is fetching result for all the blogs from the blog table.
You'll want to use a whereHas to query the relationship.
$categoryId = 1;
$productQuery = function ($query) use ($categoryId) {
// This $query object will be for the Product models, so we can treat it as
// such.
// We can query like we would on a Product, like Product::where([...]).
$query->with('category')->where('category_id', $categoryId);
};
$blogs = Blog::whereHas('product', $productQuery)
->with(['product' => $productQuery])
->get();
I've set the category ID to a variable, in case you need to change it during runtime.
Also, note that the with is completely optional.
If you exclude it, your query will run exactly the same, just without constrained eager loading. The effects of this are just that you will have to perform more database requests. The benefits come if you never actually need the relationship, then it won't have been fetch unnecessarily.
If you're curious what the SQL command will be, it will be:
SELECT * FROM `blogs`
WHERE EXISTS (
SELECT * FROM `products`
WHERE `blogs`.`product_id` = `products`.`id` AND `category_id` = ?
)
In simple terms, it will select everything from the blogs table.
It's then going to query the products table, using an inner join, to select products that have a corresponding blog entry.
The second part of the where clause is going to just get the specific character. The ? is because category_id can be any integer.
Catory with id 1
fetch its products
fetch blogs for each of its products ( map over products )
flatten the results ( since its gonna be nested for each product )
Category::find(1)->products->map->blogs->flatten();
you can use Tinker to interact with you application's query builder and eloquent models from terminal you can use :
$ php artisan tinker
For more clause you can use collection methods :
Category::find(1)->products->map->blogs->flatten()->where('status', 'Y')
->where('featured_position', 'Y')
->sortDesc('id') ;
I have this written and working as a raw SQL query, but I am trying to convert it to a more Laravel eloquent / query builder design instead of just a raw query.
My table structure like this:
Table One (Name model)
______________
| id | name |
|------------|
| 1 | bob |
| 2 | jane |
--------------
Table Two (Date Model)
_________________________________
| id | table_1_id | date |
|-------------------------------|
| 1 | 1 | 2000-01-01 |
| 2 | 1 | 2000-01-31 |
| 4 | 1 | 2000-02-28 |
| 5 | 1 | 2000-03-03 |
| 6 | 2 | 2000-01-03 |
| 7 | 2 | 2000-01-05 |
---------------------------------
I am returning only the the highest (most recent) dates from table 2 (Dates model) that match the user bob from table 1 (Name model).
For instance, in the example above, I return this from my query
2000-01-31
2000-02-28
2000-03-03
Here is what I am doing now (which works), but i'm just not sure how to use YEAR, MONTH and MAX with laravel.
DB::select(
DB::raw("
SELECT MAX(date) as max_date
FROM table_2
INNER JOIN table_1 ON table_1.id = table_2.table_1_id
WHERE table_1.name = 'bob'
GROUP BY YEAR(date), MONTH(date)
ORDER BY max_date DESC
")
);
Try this code if any problem then,
DB::table('table_1')->join('table_2', 'table_1.id','=','table_2.table_1_id')
->select(DB::raw('MAX(date) as max_date'),DB::raw('YEAR(date) year, MONTH(date) month'),'table_1.name')
->where('name','bob')
->groupBy('year','month')
->orderBy('max_date')
->get();
If any problem with above code then feel free to ask.
I have 4 tables:
"Cars" table, where every car has an ID.
"Operations" table that holds the operations have been done on a car.
| ID | CarID | Operation | User | JournalID |
| --- | ----- | --------- | ---- | --------- |
"Transactions" table that records the costs of the operations and other daily expenses, where every operation has 2 transactions, one is > 0 and the other is < 0 (for example: +100 and -100):
| ID | Account | JournalID | Amount | Date |
| --- | ------- | --------- | ------ | ---- |
"Journal" table that records the daily finance:
| ID | Amount | Date |
| --- | ------ | ---- |
What I want is knowing the sum of operations costs amount of a specific car, I was looping through all operations of that car and then looping for every journal row to sum, which lead to a bad result of course.
What can I do in that case to get the result as fast as possible?
NOTE: ALL THE NAMES OF THE COLUMNS ARE IN LOWER CASE
You need to join three tables based on the foreign keys like this and with some select and raw query you can get solution to your problem.
DB::table('cars')->join('operations','cars.id','operations.car_id')
->join('journal','journal.id','operations.journal_id')
->select(DB::raw('SUM(amount) as total_cost'),'cars.*')
->groupBy('cars.id')
->get();
I ended up solving it with #Segar's answer modified:
$result = DB::table('cars')
->join('operations','cars.id','operations.car_id')
->join('journal','journal.id','operations.journal')
->join('transactions','transactions.journal','operations.journal')->where('transactions.type', 0)
->select(DB::raw('SUM(amount) as total_cost'),'cars.*')
->groupBy('cars.id')
->get();
print_r($result);
Thanks.