mysql join 2 tables and count all rows from each table - mysql

I have table contracts c (id, exp_date) and table members m (id, cid).
I need to count all contracts and all members together joining the 2 tables on m.cid = c.id.
I tried this but obviously isn't not right as it returns a same count result from both tables
SELECT count(m.id) as totmembers , count(c.id) as totcontracts
from members m
join contracts c on m.cid = c.id
where DATEDIFF(c.im_exp, CURDATE()) > 0
Results should be something like 5000 contracts, 12.000 members but i'm getting 12.000 for both totmembers and totcontracts.

Try this:
SELECT count(m.id) as totmembers , count(distinct c.id) as totcontracts
from members m
join contracts c on m.cid = c.id
where DATEDIFF(c.im_exp, CURDATE()) > 0

Becouse you are created an INNER JOIN statement. Create a new query with two individual query int the SELECT list.
SELECT (SELECT ... WHERE ...) AS totmembers, (SELECT ... WHERE ...) AS totcontracts

Related

Any way to group the result of a DISTINCT and get the COUNT of the rows grouped correctly?

I have this query:
SELECT DISTINCT w.buyer_id, u.username, a.cb_id
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
So basically I am trying to find out how many unique entries each w.buyer_id has been involved in with regards to a.cb_id.
So to do that I ran the above query and I get a row by row result, which is good as it shows all the unique values; so I can see that user A has 14 rows (14 unique CB ID's they are involved in) and user B may have 5 rows.
So I want to make it so I can get a record set with an output of:
w.buyer_id,u.username,count
I tried the below:
SELECT DISTINCT w.buyer_id, u.username, a.cb_id, COUNT(*) AS unique_spots
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
GROUP BY w.buyer_id
LIMIT 5000;
...but it returns the COUNT as if I didn't even apply a DISTINCT to the record set.
What am I doing wrong here?
How about just writing a query to do what you want directly?
SELECT w.buyer_id, COUNT(DISTINCT a.cb_id)
FROM winners w INNER JOIN
auctions a
ON w.auction_id = a.auction_id AND a.cb_id > 0 AND
a.category_id = 1922 INNER JOIN
users u ON w.buyer_id = u.user_id
GROUP BY w.buyer_id;
The join to users seems superfluous:
SELECT w.buyer_id, COUNT(DISTINCT a.cb_id)
FROM winners w INNER JOIN
auctions a
ON w.auction_id = a.auction_id AND a.cb_id > 0 AND
a.category_id = 1922
GROUP BY w.buyer_id;
Have you tried this:
SELECT w.buyer_id, u.username, a.cb_id, COUNT(*) AS unique_spots
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
GROUP BY w.buyer_id, u.username, a.cb_id
LIMIT 5000;

MySQL - Combine Single Result Query & Multi Result Query into One

I have the 2 following Queries:
This table can have multiple lines per user (many photos) and I just want to return the number/count of photos:
SELECT COUNT(*) FROM photos WHERE photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1 AND userid='1000000002';
This table(s) is only one per user:
SELECT a.userid,a.profile_username,a.profile_gender,a.photo_name,a.photo_verified,b.profile_headline,
YEAR(DATE_SUB(NOW(), INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,d.city,c.english AS country
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
Is it possible to combine these 2 queries?
This is at my limit of ability so any advice would be great :) thx
SELECT
a.userid,
a.profile_username,
a.profile_gender,
a.photo_name,
a.photo_verified,
b.profile_headline,
YEAR(DATE_SUB(NOW(),
INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,
d.city,c.english AS country,
(SELECT COUNT(*) FROM photos WHERE photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1 AND userid= a.userid) AS result_count
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
It is possible. this takes two steps:
adapt the COUNT(*) into a filtering SUM()
plug the source table into the query
.
SELECT a.userid,a.profile_username,a.profile_gender,a.photo_name,a.photo_verified,b.profile_headline,
YEAR(DATE_SUB(NOW(), INTERVAL TO_DAYS(a.profile_birthdate) DAY)) AS age,d.city,c.english AS country
//Here we insert the count column
,IFNULL(SUM(IF(photo_description_profanity=1 AND photo_visible=1 AND photo_verified=1,1,0)),0) AS photocount
FROM login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
//Here we insert the source table
LEFT JOIN photos ON photos.userid=a.userid
WHERE a.userid IN ('1000000002','1000000003','1000000004')
//Group by users
GROUP BY a.userid
If you want this as an additional column, then cross join it into the results:
select const.cnt, . . .
from (SELECT COUNT(*) as cnt
FROM photos
WHERE photo_description_profanity=1 AND photo_visible=1 AND
photo_verified=1 AND userid='1000000002'
) const cross join
login AS a
JOIN `profiles` AS b ON a.userid=b.userid
JOIN geoCountry AS c ON a.profile_country=c.countryCode
JOIN geoWorld AS d ON a.profile_geo_location=d.pid
//Here we insert the source table
LEFT JOIN photos ON photos.userid=a.userid
WHERE a.userid IN ('1000000002','1000000003','1000000004');
The advantage of using a cross join instead of a nested select query is performance. MySQL will execute the nested select for every row in the return set. In the from clause, it will only be executed once.

Mysql query select non-members

I have 2 tables:
Customers:
- ID
- NAME
Modulemembers:
- ID
- customer_id
- enabled
I use this to enable a function of my site for some customers.
I have a form where the admin of the site can add the module for a customer, so i need a query that looks for customers that are NOT member of the modulemembers table.
I made this:
SELECT customers.id,
customers.name
FROM customers,
modulemembers
WHERE customers_id != modulemembers.cust_id
ORDER BY customers.name
but it does not work. What am I doing wrong?
You can use NOT EXISTS in the WHERE clause to get the result:
SELECT c.id,
c.name
FROM customers c
WHERE not exists (select customer_id
from modulemembers m
where c.id = m.customer_id)
order by c.name
You can use a LEFT OUTER JOIN and filter based on NULLs. The query below will pull in all results from the customers table and the modulemembers table. If there is not a match in the modulemembers table then the custid will be NULL.
SELECT c.id, c.name
FROM customers c
LEFT OUTER JOIN modulemembers m ON c.customers_id = m.cust_id
WHERE m.custid IS NULL
ORDER BY c.name
Try something like this:
SELECT c.ID AS customerId,
c.NAME AS fullName,
m.ID AS memberId
FROM Customers AS c
LEFT JOIN Modulemembers AS m ON m.customer_id = c.ID
WHERE m.ID IS NULL;

MySQL query and count from other table

I would like to get the data from one table, and count all results from other table, depending on the first table data, here is what I tried:
SELECT
cars.*, (
SELECT
COUNT(*)
FROM
uploads
WHERE
uploads.cid = cars.customer
) AS `count`,
FROM
`cars`
WHERE
customer = 11;
I dont really have an idea why its not working, as I'm not a regular MySQL user/coder...
Could anyone direct me in the right direction with this one?
SELECT
c.*, COUNT(u.cid) AS count
FROM
cars c
LEFT JOIN
uploads u
ON
u.cid=c.customer
WHERE
u.customer = 11;
GROUP BY c.cid
Try it by joining both tables using LEFT JOIN
SELECT a.customer, COUNT(b.cid) totalCount
FROM cars a
LEFT JOIN uploads b
ON a.customer = b.cid
WHERE a.customer = 11
GROUP BY a.customer
using COUNT(*) in LEFT JOIN will have records to have a minimum count of 1.
SELECT cars.*,COUNT(uploads.*) as uplloaded
from cars
left outer join uploads on uploads.cid = cars.customer
where cars.customer = 11
group by uploads.cid;
Try this :
SELECT customer, COUNT(cid) totalCount
FROM cars
INNER JOIN uploads
ON (customer = cid)
WHERE customer = 11
GROUP BY customer

SELECT count(*) on Intermediary Table with Many-Many relationship Only if Exists in Both Related Tables

I have 3 tables: users, courses and courseusers. Courseusers is the intermediary table that joins courses.idCourse with users.idUser. However, the intermediary table has no foreign key constrains and ON DELETE CASCADE or ON UPDATE CASCADE.
Users:
idUser|name
Courses:
idCourse|name
Courseusers:
id|idUser|idCourse
My question is, how do I get the top 3 most subscribed courses (most entries in courseuser), while ignoring manually deleted users from the users and courses tables (they will still exists as entries in courseuser).
What I have right now:
SELECT c.idCourse, c.name, count(*) as count
FROM courseusers as cu
JOIN course as c
ON cu.idCourse=c.idCourse
JOIN users as usr
ON (usr.idUser=u.idUser)
GROUP BY u.idCourse
ORDER BY count DESC
LIMIT 3
Try to use the following query
SELECT c.idCourse, c.name, count(*) as count
FROM courseusers as cu
LEFT JOIN course as c
ON cu.idCourse=c.idCourse
LEFT JOIN users as usr
ON (usr.idUser=u.idUser)
GROUP BY u.idCourse
ORDER BY count DESC
LIMIT 3
http://sqlfiddle.com/#!2/0567a/1
SELECT
c.name,
COUNT(1) AS total
FROM Courceusers cu
JOIN Cources c USING(idCource)
JOIN Users u USING(idUser)
GROUP BY 1
ORDER BY 2 DESC
LIMIT 3;
Join all tables based on table Users not on the intermediary table
SELECT a.idUser, a.Name, COUNT(c.idCourse) totalCount
FROM Users a
INNER JOIN CourseUsers b
ON a.idUser = b.idUser
INNER JOIN Courses c
ON b.idCourse = c.idCourse
GROUP BY a.idUser, a.Name
ORDER BY totalCount DESC
LIMIT 3
select
CourseUsers.idCourse,
Courses.name,
COUNT(distinct CourseUsers.idUser) as Subscribers
from CourseUsers
inner join Courses on CourseUsers.idCourse = Courses.idCourse
inner join Users on CourseUsers.idUser = Users.idUser
group by CourseUsers.idCourse, Courses.name
order by Subscribers desc
limit 3