I have a database of users (id, name) which is connected to database of their purchases (id, userId, price).
What I want to do is to find all users who didn't make a purchase with price 500. At first I though about such query, but it would return all rows where price is not 500, not the users themselves.
select * from purchase p
join user u on u.id = p.userId
and price != 500
Does somebody have an idea how to group it so only the users who NEVER did 500 purchase would show up?
One way is to group by the user and take only those groups having no purchase with a price of 500
select u.id, u.name
from user u
left join purchase p on u.id = p.userId
group by u.id, u.name
having sum(p.price = 500) = 0
Related
I have a query
SELECT
users.email AS email,
addons.sku AS sku,
addons.quantity as quantity,
invoices.total as total
FROM addons
INNER JOIN users ON 1=1
and users.id = addons.user_id
LEFT JOIN invoices ON 1=1
AND invoices.user_id = users.id
AND invoices.status != 3
Here is what I need to happen:
if user doesn't have an invoice at all we should include them with NULL being returned in the total
if user has an invoice in status != 3 we should include them
if invoices exists and status = 3 we should exclude them.
So it's like I need both INNER JOIN and LEFT JOIN at the same time
How can I achieve that?
This is what you need:
SELECT
users.email AS email,
addons.sku AS sku,
addons.quantity as quantity,
invoices.total as total
FROM addons
INNER JOIN users
ON users.id = addons.user_id
LEFT JOIN invoices
ON invoices.user_id = users.id
WHERE invoices.status IS NULL OR invoices.status != 3
Explanation:
Users without invoices are included in the result, with "empty" invoice total. That's what the LEFT JOIN is for
Users with invoice status != 3 are included, and so are their invoices. So, add that to the where clause (remember the status could be NULL because of the above LEFT JOIN)
Users with invoice status = 3 are excluded. Do that with the WHERE clause
I wanna count all the orders a user has and all the complete orders a user has. I came with this but it´s not working
select
count(a.id) as total,
count(b.id) as complete
from
user
join
orders a on user.id = a.user_id
join
orders b on user.id = b.user_id
where
a.id = 1
and
(b.id = 1 and b.complete = 'yes');
Any idea?
you could sum the order with yes and count the distinct id group by user
select user.id, sum(if(a.complete ='yes',1,0)), count(distinct a.id)
from user
INNER join orders a on user.id = a.user_id
group by user.id
I believe you are searching for grouping (MySQL GROUP BY) by the differents users, and then count all the orders related to each user plus the completed ones. For this approach, you will need to:
(1) Join users with they orders.
(2) Use GROUP BY clause on user.id column.
(3) Count all orders related to each user with COUNT()
(4) Sum all orders related to each user having some specific condition with SUM(CASE WHEN <specific_condition> THEN 1 ELSE 0 END).
In summary, a query like next one should work:
SELECT
u.id,
COUNT(o.id) AS total_orders,
SUM(CASE WHEN o.complete = "yes" THEN 1 ELSE 0 END) AS complete_orders
FROM
user AS u
INNER JOIN
orders AS o ON o.user_id = u.id
GROUP BY
u.id
I have a table called Purchases which belongs to a Users (that is a Purchase has a foreign key to User).
The Purchases table has a column called quantity and a state_id column, both are integers.
I want to be able to order the Users by their completed purchases (state_id = 10) where the SUM of their quantities is bigger than > 100. That is, all the users which have a total of completed purchases > 100, should appear first, and the rest right after.
This is what I have tried:
SELECT users.id as user_id,
SUM(CASE WHEN purchases.state_id = 5
THEN purchases.quantity
ELSE 0
END) as quantity
FROM users
LEFT OUTER JOIN purchases ON purchases.user_id = users.id
GROUP BY purchases.user_id
But this is just returning me one User, not all of them. What am I missing?
You can JOIN only completed purchases using JOIN condition. And you should group by users.id not purchases.user_id as soon you can have users in a table without purchases at all:
SELECT users.id as user_id,
SUM(purchases.quantity) as quantity
FROM users
LEFT JOIN purchases ON (users.id=purchases.user_id)
AND (purchases.state_id = 10)
GROUP BY users.id
ORDER BY quantity DESC
I am struggling to get the correct syntax for what I need and wondered if anyone could help?
I have 3 tables: users, owneditems and shopitems
From users I need to get userid and city
From owneditems I need to get userid and itemid
From shopitems I need to get id and city
userid on owneditems and users will be the same
itemid on owneditems will be the same as id on shopitems
city on shopitems and users will be the same
What I'm after is to find out which city the users are in and tie up which items they own in that city.
The syntax I tried using was
SELECT users.city, users.id, shopitems.city, shopitems.id, owneditems.itemid, owneditems.userid
FROM users, shopitems, owneditems
WHERE users.city = shopitems.city
AND owneditems.itemid = shopitems.it
AND users.id = owneditems.userid
It is not exactly clear what you are trying to do, but have you tried using a LEFT JOIN instead of the INNER JOIN:
select u.city,
u.id,
s.city,
s.id,
o.itemid,
o.userid
from users u
left join owneditems o
on u.id = o.userid
left join shopitems s
on u.city = s.sity
and o.itemid = s.itemid
I have two tables:
users table
list of users
stories
list of stories - multiple stories per user
I want to know the average number of stories a user has. (not a specific user, for all users)
Expected results: 2.3 average stories per user
Tried:
select avg(w) from (select count(distinct user_id) as w from stories group by user_id) a;
above ran but didn't seem correct
also:
SELECT user_id, ( SELECT COUNT(*) FROM stories w WHERE w.user_id = u.user_id ) as TotalStories FROM user u;
returned average stories for each user, not average for overall
First you need to know the number of stories per user:
select count(s.id) as n
from users u left outer join stories s on u.id = s.user_id
group by u.id
Then just apply avg to that:
select avg(n)
from (
select count(s.id) as n
from users u left outer join stories s on u.id = s.user_id
group by u.id
) as dt
SELECT COUNT(userid) AS totalusers, SUM(storycount) AS totalstories, SUM(storycount) / COUNT(userid) AS average_stories
FROM (
SELECT users.id AS userid, COUNT(stories.id) AS storycount
FROM users
LEFT JOIN stories ON (users.id = stories.user_id)
GROUP BY users.id
) AS child
Inner query does the per-user story counting. Outer query counts the total users, total stories, and the stories per user average.