My code
$result=DB::table('receipts')
->join('dealer_m','receipts.ToDealerID','dealer_m.DealerID')
->join('dealer_m','receipts.FromDealerID','dealer_m.DealerID')
->join('product_m','receipts.ProductID','product_m.ProductID')->get();
table receipts
Id | FromDealerId | ToDealerId | ProductId
---+---------------+-------------+------------
1 1 2 1
2 1 3 1
3 3 1 1
Table dealer_m
DealerId | DealerName
---------+-----------
1 Dealer One
2 Dealer Two
3 Dealer Three
Table product_m
ProductId | ProductName
----------+-----------
1 Product One
2 Product Two
Expected Output
Id | FromDealerId | ToDealerId | ProductId | FromDealerName | ToDealerName | ProductName
---+---------------+-------------+------------+----------------+--------------+------------
1 1 2 1 Dealer One Dealer Two Product One
2 1 3 1 Dealer One Dealer Three Product One
3 3 1 1 Dealer Three Dealer One Product One
When I run my code it gets an error
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique
table/alias: 'dealer_m' (SQL: select '' from 'receipts' inner join
'dealer_m' on 'receipts'.'ToDealerID' = `dealer_m'.'DealerID' inner
join 'dealer_m' on 'receipts'.'FromDealerID' = 'dealer_m'.'DealerID'
inner join 'product_m' on 'receipts'.'ProductID' =
'product_m'.'ProductID')
How to solve this ???
Thank You
Try This:
$results=DB::table('receipts')
->select('receipts.*','dealer_m1.DealerName as ToDealer','dealer_m2.DealerName as FromDealer','product_m.ProductName')
->join('dealer_m as dealer1','receipts.ToDealerID','dealer_m.DealerID')
->join('dealer_m as dealer2','receipts.FromDealerID','dealer_m.DealerID')
->join('product_m','receipts.ProductID','product_m.ProductID')->get();
You just need to give each joined table an alias
Now in your blade:
#foreach ($results as $result)
<tr>
<td>{{$result->Id}}</td>
<td>{{$result->FromDealerId}}</td>
<td>{{$result->ToDealerId}}</td>
<td>{{$result->ProductId}}</td>
<td>{{$result->FromDealer}}</td>
<td>{{$result->ToDealer}}</td>
<td>{{$result->ProductName}}</td>
</tr>
#endforeach
Of course if you ever get stuck on what to call in your blade, just print our the collection to find the key => values or do dd($results); in the controller to inspect it before it gets to the view.
You should try this:
$result=DB::table('receipts')
->join('dealer_m as dealer_id','receipts.ToDealerID','dealer_m.DealerID')
->join('dealer_m as dealer_f_id','receipts.FromDealerID','dealer_m.DealerID')
->join('dealer_m as product_p_id','receipts.ProductID','product_m.ProductID')->get();
Related
I have one shop table and one item table. Shop table has many item, and my problem is I want to search multiple items that available in one shop.
shop table
id | name
---------
1 | Shop 1
2 | Shop 2
Item table
id | name | shop_id
----------------------
1 | JRC | 1
2 | sukhoy | 1
3 | sukhoy | 2
When I want to find item jrc and sukhoy, so it must showing Shop 1, because both two items are ready on Shop 1.
My expected output is
Output table
id | shopName | itemName
------------------------
1 | Shop 1 | JRC
2 | Shop 1 | sukhoy
My query is
select * from shops
inner join products as produk2 on produk2.shopId = shops.id and (produk2.name like "%sukhoy%")
inner join products as produk on produk.shopId = shops.id and (produk.name like "%jrc%")
It works because it using different alias per inner join.
But what I want is, how to combine the output from that 2 join without define different alias. Or how I can combine join result into one same column ?
I think this does what you want:
select p.shop_id
from products p
group by p.shop_id
having sum(p.name like '%jrc%') > 0 and
sum(p.name like '%sukhoy%') > 0;
This returns shop ids that have both products. Of course, you can join the results to shops to get more information about the shops.
You can just use one join:
select * from shops
inner join products as produk
on produk.shopId = shops.id
and (produk.name like "%jrc%" OR produk.name like "%sukhoy%")
I am trying to find one query that returns all people including the company they belong to and companies that do not have any person assigned yet.
Company
cid | cname
--------------
1 Company 1
2 Company 2
Person
pid | pname | fk_company
---------------------------
1 Person 1 1
2 Person 2 1
desired result
pid | pname | fk_company | cid | cname
----------------------------------------------
1 Person 1 1 1 Company 1
2 Person 2 1 1 Company 1
NULL NULL NULL 2 Company 2
Thanks in advance
If you want everything from both tables, regardless of match left AND right, you need a FULL JOIN:
SELECT *
FROM person
FULL JOIN company
ON person.fk_company = company.cid
edit: Apparently mysql doesn't support FULL JOIN. You'll have to do both LEFT JOINS by hand and UNION ALL them.
You should mention something you tried. Anyway, I will explain the method so you can work on it.
SELECT <column_names>FROM <table1_name> LEFT JOIN <table2_name>ON
<table1.column_name> = <table2.column_name>;
For more explanations please refer this link.
SQL Left Join
I have four tables, products, priceplans, and two category tables as follows:
products
---------
product_id
a
b
priceplans
---------
priceplan_id
a
b
product_id (can be null)
price
categoryA
---------
a (id)
category_name
categoryB
---------
b (id)
category_name
In the priceplans a and b are category ids in other tables, the combination (a,b,product_id) is unique but product_id can also be null, and the priceplan should then use the general priceplan for the (a,b,null) combination. That is the theory, but it is not working out as well as I had hoped and I havent managed to construct a query to only filter them out.
Example:
products - 3 products, 2 in the same category, one in another category
product_id a b
1 1 1
2 1 1
3 1 2
priceplans - 3 plans,
1 is for the default (a,b)=(1,1) category combination when there is no product_id,
2 is supposed to override the default as we have declared a product_id, and
3 is the default for (a,b)=(1,2) combination
priceplan_id a b product_id price
1 1 1 null 10
2 1 1 2 15
3 1 2 null 12
What I want the outcome to look like when I join products with the priceplans is:
product_id a b priceplan_id price
1 1 1 1 10
2 1 1 2 15
3 1 2 3 12
If for the product with a category combination (a,b)=(1,1) and id=1 i want the priceplan with combination (a,b,1) if it exists, if not i want the (a,b,null) priceplan. Any suggestions?
I finally managed to create the query I was looking for:
select pro.*, pp.* from products pro
left join price_plans pp
on pro.a=pp.a
and pro.b=pp.b
and (pro.product_id=pp.product_id or pp.product_id is null)
left join price_plans pp2
on pro.a=pp2.a
and pro.b=pp2.b
and pp2.product_id =pro.product_id
where pp.product_id <=> pp2.product_id
MySQL 5.6
We have two tables: cars and views.
Cars Views
---+------- ---+-------
id | desc id | car_id
---+------- ---+-------
1 | desc1 1 | 1
2 | Desc1 2 | 2
3 | desc2 3 | 3
The problem is with the desc field in the table cars. That row had to be unique but we unfortunately allowed the users to fill in uppercased values, which brought us to the situation of having (according to the example above) two duplicated rows: desc1 and Desc1.
The way to fix that is DELETE the duplicated cars, and keep only the first one. We know how to deal with that.
Our problem comes before that, when updating the related table, where some views are associated to a car which has a duplicated desc (for instance a car which is going to be removed). Those views should be updated for being assigned to the first of the duplicated cars (in this case the car id #1)
After the UPDATE, we'd like this result in views:
Views
---+-------
id | car_id
1 | 1
2 | 1
3 | 3
We are able to get all the ids of the duplicated cars and deal with the deletion but we're stuck with this UPDATE.
The solution will be to create a mapping table with before/after values for description ids.
The result should look something like:
Before | After
---------------
1 | 1
2 | 1
3 | 3
That table can be created with something like this:
SELECT
cars.id AS before_id,
fixed.lowest_id AS after_id
FROM cars
JOIN (
-- The lowest id value for each duplicate description
SELECT
MIN(id) AS lowest_id,
LOWER(desc) AS lower_desc
FROM cars
GROUP BY LOWER(desc)
) fixed
ON LOWER(cars.desc) = fixed.lower_desc
You can then have your views match to that mapping table to pull the new "correct" id value.
UPDATE Views AS v
JOIN (SELECT c1.id AS oldID, MIN(c2.id) AS newID
FROM Cars AS c1
JOIN Cars AS c2 ON LOWER(c1.desc) = LOWER(c2.desc)
HAVING oldID != newID) AS c
ON v.car_id = oldID
SET v.car_id = newID
The subquery finds the primary ID for each ID that contains a duplicate description. Joining this with the Views table provides the information needed to make the replacements.
I'm having 2 tables. Table A contains a list of people who booked for an event, table B has a list of people the booker from table A brings with him/her. Both tables have many colums with unique data that I need to do certain calculations on in PHP , and as of now I do so by doing queries on the tables with a recursive PHP function to resolve it. I want to simplify the PHP and reduce the amount of queries that come from this recursive function by doing better MYSQL queries but I'm kind of stuck.
Because the table has way to many columns I will give an Excerpt of table A instead:
booking_id | A_customer | A_insurance
1 | 134 | 4
Excerpt of table B:
id | booking_id | B_insurance
1 | 1 | 0
2 | 1 | 1
3 | 1 | 1
4 | 1 | 3
The booking_id in table A is unique and set to auto increment, the booking_id in table b can occur many times (depending on how many guests the client from table A brings with him). Lets say I want to know every selected insurance from customer 134 and his guests, then I want the output like this:
booking_id | insurance
1 | 4
1 | 0
1 | 1
1 | 1
1 | 3
I have tried a couple of joins and this is the closest I've came yet, unfortunately this fails to show the row from A and only shows the matching rows in B.
SELECT a.booking_id,a.A_customer,a.A_insurance,b.booking_id,b.insurance FROM b INNER JOIN a ON (b.booking_id = a.booking_id) WHERE a.booking_id = 134
Can someone point me into the right direction ?
Please note: I have altered the table and column names for stackoverflow so it's easy for you guys to read, so it's possible that there is a typo that would break the query in it right now.
I think you need a union all for this:
select a.booking_id, a.insurance
from a
where a.a_customer = 134
union all
select b.booking_id, b.insurance
from a join
b
on a.booking_id = b.booking_id
where a.a_customer = 134;
The simplest way I can think of to achieve this is to use a UNION:
SELECT booking_id, A_insurance insurance
FROM A
WHERE booking_id = 134
UNION
SELECT booking_id, B_insurance insurance
FROM B
WHERE booking_id = 134
As my understanging of your isso is right, that should give you the result you need:
SELECT a.booking_id,a.insurance FROM a WHERE a.booking_id = 134
union
SELECT a.booking_id,b.insurance FROM b INNER JOIN a ON (b.booking_id = a.booking_id) WHERE a.booking_id = 134