i have a sql sub-select to list how many orders there are and their total value:
SELECT u.name,
(SELECT COUNT(*) FROM orders o WHERE o.user_id=u.id
) AS order_count,
(SELECT SUM(oi.quantity * p.price)
FROM orders AS o
INNER JOIN order_items AS oi
ON oi.order_id = o.id
INNER JOIN products AS p
ON p.id = oi.product_id
WHERE o.user_id=u.id
) AS total_price
FROM users u
ORDER BY total_price DESC
Any ideas how can i do that without sub-select?
You can convert the correlated subqueries (O(N^2) performance) into LEFT JOIN
SELECT u.name,
o.order_count,
o2.total_price
FROM users u left join (
SELECT user_id, COUNT(*) order_count
FROM orders
GROUP BY user_id
) o
on u.id = o.user_id
left join (
SELECT o.user_id, SUM(oi.quantity * p.price) total_price
FROM orders o
INNER JOIN order_items oi
ON oi.order_id = o.id
INNER JOIN products p
ON p.id = oi.product_id
GROUP BY o.user_id
) o2 on u.id = o2.user_id
ORDER BY total_price DESC;
You can use Left Join
SELECT u.NAME,
AS order_count,
total_price
FROM users u
LEFT JOIN (SELECT Count(*) AS order_count,
user_id
FROM orders
GROUP BY user_id) p
ON o.user_id = u.id
LEFT JOIN (SELECT Sum(oi.quantity * p.price) AS total_price,
o.user_id
FROM orders AS o
INNER JOIN order_items AS oi
ON oi.order_id = o.id
INNER JOIN products AS p
ON p.id = oi.product_id
GROUP BY o.user_id) so
ON so.user_id = u.id
ORDER BY total_price DESC
Here's the same query with one sub query (NOTE not tested for syntax but you get the idea):
select u.name, count(*) orderCount, sum(totalOrder) total order
from users u
join (select userid, o.id, sum(oi.quantity * p.price) totalorder
from orders o
join order_items as oi on oi.order_id = o.orderid
join products p on oi.product_id = p.id
group by userid, o.id) x
on u.id = x.user_id
group by u.name
Related
I'm struggling to convert this below MySQL query into laravel query builder. It has a lot of joins and subqueries inside. Can someone please help me?
MYSQL query:
SELECT a.id , b.*, a.agent_id, td.contacts, td.addresses
FROM teams a
left join team_details as td on td.team_id = a.id
LEFT OUTER JOIN
(
SELECT m.id, m.due_date, t.team_id, m.department, m.assigned_to , cm.title, u.name
FROM (
SELECT team_id, MAX(due_date) AS due_date
FROM campaign_activities where task_status=false and due_date is not null
GROUP BY team_id
) t JOIN campaign_activities m ON m.team_id = t.team_id AND t.due_date = m.due_date
left join campaign_activity_masters cm on cm.id = m.camp_activity_id
left join users u on u.id = m.assigned_to
) b ON a.id = b.team_id
order by a.id
I'm trying something like below but got stuck with LEFT OUTER JOIN as it has sub query inside :).
DB::table('teams as a')
->leftjoin('team_details as td', 'td.team_id','=','a.id')
->select('a.id', 'b.*', 'a.agent_id','td.contacts','td.addresses')
->leftouterjoin(DB::select(DB::raw('SELECT m.id, m.due_date, t.team_id, m.department, m.assigned_to , cm.title, u.name
FROM (
SELECT team_id, MAX(due_date) AS due_date
FROM campaign_activities where task_status=false and due_date is not null
GROUP BY team_id
) t JOIN campaign_activities m ON m.team_id = t.team_id AND t.due_date = m.due_date
left join campaign_activity_masters cm on cm.id = m.camp_activity_id
left join users u on u.id = m.assigned_to')))
->get();
Any suggestions, please? I want to apply paginate function paginate() instead of get() for this query builder.
I think you should try.
$cards = DB::select("SELECT a.id , b.*, a.agent_id, td.contacts, td.addresses
FROM teams a
left join team_details as td on td.team_id = a.id
LEFT OUTER JOIN
(
SELECT m.id, m.due_date, t.team_id, m.department, m.assigned_to , cm.title, u.name
FROM (
SELECT team_id, MAX(due_date) AS due_date
FROM campaign_activities where task_status=false and due_date is not null
GROUP BY team_id
) t JOIN campaign_activities m ON m.team_id = t.team_id AND t.due_date = m.due_date
left join campaign_activity_masters cm on cm.id = m.camp_activity_id
left join users u on u.id = m.assigned_to
) b ON a.id = b.team_id
order by a.id");
Hope it help you.
I have created one SQL sub-query which was running perfectly.
SELECT o.*, u.*,OD.* FROM orders o
LEFT JOIN order_details OD on o.id = OD.order_id
LEFT JOIN users u ON o.user_id = u.id
WHERE o.order_status = 1 AND o.id NOT IN
(SELECT r.order_id FROM order_rejected_details r WHERE r.courier_id =$courierId)
order by o.id desc
How to write above query with NOT in condition in CakePHP?
You can simply write this query in CakePHP as per below.
In model:
$resultData = $this->query('SELECT o.*,
u.*,
OD.*
FROM orders o
LEFT JOIN order_details OD
ON o.id = OD.order_id
LEFT JOIN users u
ON o.user_id = u.id
WHERE o.order_status = 1
AND o.id NOT IN (SELECT r.order_id
FROM order_rejected_details r
WHERE r.courier_id = $courierid)
ORDER BY o.id DESC');
return $resultData;
I am trying to add my users table to my existing query so that I can match the users.id with the forum_topics.topic_creator, so I can match those and enable myself to assign that with that users username.
This is my original query.
$query2 = mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t JOIN forum_posts
AS p on t.id = p.topic_id WHERE t.category_id = ".$cid."
GROUP BY t.id DESC")
I then tried doing this..
$query2 =mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t JOIN forum_posts
AS p on t.id = p.topic_id WHERE t.category_id = ".$cid."
INNER JOIN users AS u
ON t.topic_creator = u.id
GROUP BY t.id DESC")
or die ("Query2 failed: %s\n".($query2->error));
I am getting the fail message.
What am I doing wrong?
WHERE clause should come after join:
SELECT t.*, COUNT(p.topic_id) AS tid2
FROM forum_topics AS t JOIN
forum_posts AS p on t.id = p.topic_id INNER JOIN
users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC
EDIT:
To select the username as well:
SELECT t.*,u.username, COUNT(p.topic_id) AS tid2
FROM forum_topics AS t JOIN
forum_posts AS p on t.id = p.topic_id INNER JOIN
users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC
The WHERE clause has to be placed after the INNER JOIN.
$query2 =mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t
JOIN forum_posts AS p ON t.id = p.topic_id
INNER JOIN users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC")
or die ("Query2 failed: %s\n".($query2->error));
Try this
SELECT t.*, COUNT(p.topic_id) AS tid2
FROM forum_topics t
JOIN forum_posts p ON (t.id = p.topic_id )
INNER JOIN users u ON (t.topic_creator = u.id)
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC`
i want to use JOIN categories c ON c.id = i.category if post_type is 1 and i want to have c.title AS category_name, in SELECT otherwise JOIN categories c ON c.id = i.category and c.title AS category_name, must be not worked in query , i'm using case for join but my sql command is not correct. please help me. in all description my quastion means is how to change this below command to if post_type is 1 join must be not work
SELECT SQL_CALC_FOUND_ROWS
i. * ,
c.title AS category_name,
s.title AS status_title,
i.thumb_image,
CONCAT( u.name, ' ', u.family ) AS author
FROM contents i
LEFT JOIN categories c
ON i.category = CASE post_type WHEN 1 then c.id END
JOIN users u ON u.id = i.posted_by
JOIN status_topics s ON s.id = i.t_status
WHERE i.id = 2
I would always do the LEFT JOIN and put a condition on the column itself:
SELECT SQL_CALC_FOUND_ROWS
i. * ,
IF(i.post_type = 1, c.title, NULL) AS category_name,
s.title AS status_title,
i.thumb_image,
CONCAT( u.name, ' ', u.family ) AS author
FROM contents i
LEFT JOIN categories c ON i.category = c.id
JOIN users u ON u.id = i.posted_by
JOIN status_topics s ON s.id = i.t_status
WHERE i.id = 2
Hello can anybody see why this query fails?
SELECT A.idAd, A.ads_in_Cat, A.title, A.currency, A.price,
A.in_dpt, A.description, A.featured FROM ads A
LEFT JOIN featured F ON F.ad = A.idAd
INNER JOIN dept D ON D.id_dept = A.in_dpt
INNER JOIN sub_cat_ad S ON S.id_sub_cat = A.ads_in_Cat
INNER JOIN cat_ad C ON C.idCat_ad = S.from_cat_ad
ORDER BY A.featured DESC LIMIT :limit, :offset
But this one works:
SELECT *FROM ads
LEFT JOIN featured ON featured.ad = ads.idAd
INNER JOIN dept ON dept.id_dept = ads.in_dpt
INNER JOIN sub_cat_ad ON id_sub_cat = ads.ads_in_Cat
INNER JOIN cat_ad ON idCat_ad = sub_cat_ad.from_cat_ad
ORDER BY featured DESC LIMIT :limit, :offset
In the first one, I don't want all columns from the table "ads", the query returns only columns till ...FROM ads A.
If you specify to only select fields from A that's what you get: Only fields from A.
If you want fields from other tables too you have to specify them as well.
SELECT
A.idAd, A.ads_in_Cat, A.title, A.currency, A.price, A.in_dpt, A.description, A.featured,
F.*,
D.*,
S.*,
C.*
FROM ads A
LEFT JOIN featured F ON F.ad = A.idAd
INNER JOIN dept D ON D.id_dept = A.in_dpt
INNER JOIN sub_cat_ad S ON S.id_sub_cat = A.ads_in_Cat
INNER JOIN cat_ad C ON C.idCat_ad = S.from_cat_ad
ORDER BY A.featured DESC LIMIT :limit, :offset