How get needed rows from 3 table in Laravel 5.5 - php

I have 3 tables, Order, Products, Order_Products. I need get all field from order and products, thats ok using hasManyThrough(). But i need 1 more field from Order_products. How can i get this field ?
public function products()
{
//in order model
return $this->hasManyThrough('App\Models\Product','App\Models\OrderProduct','order_id','id','id','product_id');
}
using sql i need query like
SELECT
products.*, order_products.order_id, order_products.count as order_count
FROM
products
INNER JOIN order_products ON order_products.product_id = products.id
WHERE
order_products.order_id = 2

You can access intermediate table fields by using pivot attribute on model.
Lets say you have product, Then you can access count field of orders_products
$product->pivot->count;

Related

Select only those records that have multiple value in same table

I have only those rows that have multiple rows in the same table. For example see below image.
In the above picture you can see 2 highlighted columns one is for useid(u_id) and second is for product id (product_id).
So you can see user id of 7 has multiple product like (78,40,44,45,53) and user id 9 has multiple products like (79,75,79) same like user id 40 has multiple products.
so want out put like if particular user have multiple products then it will display 'multiple product' in product name column instead of display all product name.
above picture display all product but i need to display 'multiple product' message instead of all products if particular user have multiple products
I have used following query but not getting result that i want .
SELECT *
FROM orderlist
WHERE product_id IN (
SELECT product_id
FROM orderlist
GROUP BY product_id
HAVING COUNT(*) > 1
)
You could do the JOINS after aggregation
SELECT *,
CASE WHEN c.Counts > 1 THEN 'Multi' ELSE o.ProductName END ProductName
FROM
(
SELECT product_id, COUNT(*) Counts
FROM orderlist
GROUP BY product_id
)c INNER JOIN orderlist o ON o.product_id = c.product_id

QueryBuilder: Sum values of a pivot table

I'm new on Laravel & Eloquent. I have Users, Products and Votes tables on my DB. Users can vote (0 to 5) on products, so it is a "many to many" relationship, with the Votes table acting like a pivot:
Users: id, name, email, password
Products: id, name, model, brand
Votes: user_id, product_id, vote
I mapped this schema like this:
// User model:
public function product_votes()
{
return $this->belongsToMany('App\Product', 'votes')->withPivot('vote');
}
// Product model:
public function product_votes()
{
return $this->belongsToMany('App\User', 'votes')->withPivot('vote');
}
So John can vote 5 on product X and 0 on product Y. Bob can vote 2 on product X, 3 on product Y, and so on...
I'm trying to query all products, with the sum of votes of each one of them. Something like:
SELECT p.*, (SUM(v.vote) / COUNT(*)) as votes FROM products p INNER JOIN votes v on v.product_id = p.id GROUP BY p.id
How can I do that with QueryBuilder? My mapping is right?
The following will do the trick:
Product::select('products.*', DB::raw('SUM(vote)/COUNT(*) as votes'))
->join('votes', 'votes.product_id', '=', 'products.id')
->groupBy('products.id')
->get();
You can see the query that will be run by calling toSql() instead of get().

Select entities assuming related entity does not exist

My entity (Product) has a unidirectional many-many relation with another entity (Company) called deletedByCompanies.
I wish to select all Products that has not been deleted by a particular company. That is all products that are not connected through that many-many relation.
Tried:
$this->em->getRepository(Product::class)->createQueryBuilder('t')
->leftJoin('t.deletedByCompanies', 'deletedCompany')
->andWhere('deletedCompany.id not in (:companyId)')
->setParameter('companyId', [$companyId]);
But this simply does not return anything.
Schema is pretty straghtforward:
Product:
id: int PK
Company:
id: int PK
DeletedProducts
product_id: int FK
company_id: int FK
Entity definition in Product class:
/**
* #var Company[]
* #ORM\ManyToMany(targetEntity="Company", indexBy="id")
* #ORM\JoinTable(name="DeletedProducts")
*/
protected $deletedByCompanies;
I think you can solve your problem with a NOT EXISTS clause on the deletedby table.
In the SQL dialect:
SELECT * FROM product p WHERE NOT EXISTS
(SELECT * FROM DeletedProducts d WHERE p.id=d.product_id AND company_id = 2 );
In the Doctrine2 DQL, we haven't the entity DeletedProducts so we have to do a bit more stuff like:
$qb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('t')
->Join('t.deletedByCompanies', 'deletedCompany')
->andWhere('deletedCompany.id in (:companyId)')
->andWhere("p=t");
$mainQb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('p');
$mainQb->where($mainQb->expr()->not($mainQb->expr()->exists($qb->getDQL())));
$mainQb->setParameter('companyId', [$companyId]);
var_dump($mainQb->getQuery()->getSql());
$res =$mainQb->getQuery()->execute();
Let me know if I don't understand your problem.
Hope this help
I'm not familiar with Doctrine, but I'm trying to help with some SQL knowledge. Following query should do what you want:
SELECT DISTINCT Product.* FROM Product
LEFT JOIN DeletedProducts on product_id = product.id
WHERE product_id IS NULL OR product_id !=
ALL( SELECT product_id FROM DeletedProducts WHERE company_id = 2 )
Some Explanation...
DISTINCT: Nessacary keyword to prevent redundancy. The same product can appear multiple times in the result of the Left Join if it is deleted by . DISTINCT eliminates those duplicates.
WHERE product_id IS NULL: The Left Join will also list the products which are not related to any company over the "DeletedProducts"-table. Since there is no relation the fields product_id and company_id are NULL.
OR product_id != ALL( [...] ): Now that we have got the products which aren't deleted by any company, we need additionally those which aren't deleted by a particular company. So we use an OR with a subquery which selects all deleted products of a certain company (e.g. company id = 2 as in the code example). Since we want to have the not-deleted products we have to use the "!="-Operator.
I hope this helps a little. Now it's up to you to "translate" the query for the usage within Doctrine.

joining tables in mySQL to get a particular column

I have two tables :
- cart , cols are (painting_id, session_id, ip, user_agent)
- paintings , cols (painting_id, price)
Now I have to select the painting id from the table cart. I need to Join the two tables and get the sum of the price of all the paintings from table 'paintings'. Note the table cart doesnt have the price column , it has to be imported from the 'paintings' table. Only the sum of price of those paintings are shown which has been added into the cart table by a particular session id or email id.
Here is the query i have tried so far
SELECT p.SUM(price) FROM paintings
p JOIN cart c ON p.painting_id = c.painting_id
WHERE c.session_id = '$session'
It should be SUM(p.price) instead.
Try this query
SELECT cart.user_agent, sum(paintings.price)
from cart inner join
paintings on
cart.painting_id=paintings.painting_id
where session_id='$session'
if you want the total cost of all the users
SELECT cart.user_agent, sum(paintings.price)
from cart inner join
paintings on
cart.painting_id=paintings.painting_id
group by cart.session_id

MySQL associated table COUNT() and GROUP BY

I am doing a pretty normal routine, but having a tough time getting my output correct.
I have two tables: *ads_list* (listings) and *ads_cate* (categories).
I am currently displaying my category list like so:
SELECT id, cateName FROM ads_cate ORDER BY cateName
What I am trying to achieve: count of all items in each category in this format:
Category | Number of Ads
categoryName 56
This is my current code, and have been tweaking but getting no output in my array:
SELECT
ads_cate.id,
ads_cate.cateName, // Category Name
ads_list.id,
ads_list.COUNT(title), // Title of ad
ads_list.Category // Relational Category ID INT(11)
FROM
ads_cate,
ads_list
GROUP BY cateName
ORDER BY cateName
I am calling in all required fields and running a COUNT() on my title field (as these are unique for each ad) and then I am grouping by cateName which also seems correct.
See what this gives you. I think it is what you need.
SELECT
ads_cate.cateName, // Category Name
COUNT(ads_list.id), // Title of ad
FROM
ads_cate
INNER JOIN
ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
ORDER BY cateName

Categories