Query to join and count rows in mysql - mysql

I have two table portal and login table.How to get count of portal_id in login table and join with portal table. If there is no matching row exists in login table show as null value
$this->db->select("a.name");
$this->db->from("{$this->Portal} a");
$this->db->join("{$this->login} b","a.id = b.portal_id");
$this->db->order_by("a.portal_id asc");
Table portal
id | name
1 | john
2 | steve
3 | ricky
4 | richard
Table Login
portal_id | city
1 | Bangalore
2 | Ludhiana
1 | Chandighara
2 | Delhi
Result Table
id | name | count
1 | john | 2
2 | steve | 2
3 | ricky | null

Simple left join needs to be used, to get the counts as null instead of zero you can use nullif
select p.id,
p.name,
NULLIF(count(l.portal_id), 0) as
portal_logn_count
from portal p left join login l on p.id =
l.portal_id
group by p.id,p.name
order by p.id,p.name

SELECT p.id, p.name, COUNT(l.id) AS `count`
FROM portal p
LEFT JOIN Login l ON l.portal_id = p.id
GROUP BY p.id

$this->db->select("a.id,a.name,count(a.id)");
$this->db->from("{$this->Portal} a");
$this->db->join("{$this->login} b","a.id = b.portal_id", 'left');
$this->db->group_by("a.id");
$this->db->order_by("a.id asc");
Making a query like
Select a.id, a.name, count(a.id) from portal a
left join login b on a.id = b.portal_id
group by a.id
order by a.id asc

Works Perfectly....
Select a.id, a.name, NULLIF(count(b.portal_id ), 0) from portal a
left join Login b on a.id = b.portal_id
group by a.id
order by a.id asc

Related

MYSQL - Group Contact rows with records NOT IN

My case looks simple but i'm messing around with this..
I have 4 tables: User, Macros, Categories, and another one that relate users with categories. One Macro have many Categories.
What i need, is a query that based on the Macro, get the users and the Categories where user is NOT IN.
Example: I have a macro named VEICULES, with categories CAR,TRUCK and Motorcycle. User José is on category CAR and User Julio on category CAR and TRUCK, so my query should return:
José | TRUCK,Motorcycle
Julio | Motorcycle
Tables:
prd_users
id | name | Email
---------------------------
1 | José | jose#email.com
2 | Júlio | julio#email.com
3 | André | andre#email.com
cat_macros
macro_id | macro_name
-----------------------
1 | Veicules |
cat_categories
category_id | category_name | macro_id
---------------------------------------
1 | Cars | 1
2 | Trucks | 1
3 | Motorcycles | 1
prd_tr_rabbit_catg
id | category_id | tasker_user_id
---------------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
I'm stucked on just getting the categories where the user already is ..
SELECT prd_users.id, prd_users.name,
prd_users.email,cat_macros.macro_name as macro,
GROUP_CONCAT(cat_categories.category_name SEPARATOR ', ') as in_categories
FROM prd_users
INNER JOIN prd_tr_rabbit_catg ON prd_tr_rabbit_catg.tasker_user_id = prd_users.id
INNER JOIN cat_categories ON cat_categories.category_id = prd_tr_rabbit_catg.category_id
INNER JOIN cat_macros ON cat_macros.macro_id = cat_categories.macro_id
WHERE cat_macros.macro_id = '45'
GROUP BY prd_users.id;
To solve this problem it's necessary to create a list of all users joined with all categories for the given macro category. This can be done with a CROSS JOIN:
SELECT *
FROM prd_users u
CROSS JOIN (SELECT m.macro_id, m.macro_name, c.category_name, c.category_id
FROM cat_macros m
JOIN cat_categories c ON c.macro_id = m.macro_id) c
This can then be LEFT JOINed to the prd_tr_rabbit_catg table and by selecting those rows where there is no matching entry in the prd_tr_rabbit_catg table, we can find the users who don't have an entry for the given category:
SELECT c.macro_name, u.id AS user_id, u.name, u.Email, GROUP_CONCAT(c.category_name) AS missing_cats
FROM prd_users u
CROSS JOIN (SELECT m.macro_id, m.macro_name, c.category_name, c.category_id
FROM cat_macros m
JOIN cat_categories c ON c.macro_id = m.macro_id) c
LEFT JOIN prd_tr_rabbit_catg x ON x.tasker_user_id = u.id AND x.category_id = c.category_id
WHERE x.id IS NULL
AND c.macro_id = 1
GROUP BY c.macro_name, u.id
For your sample data, this gives:
macro_name user_id name Email missing_cats
Veicules 1 José jose#email.com Motorcycles,Trucks
Veicules 2 Júlio julio#email.com Motorcycles
Veicules 3 André andre#email.com Cars,Motorcycles,Trucks
Update
To exclude users who don't have any of the categories, add a HAVING clause:
HAVING COUNT(*) < (SELECT COUNT(*) FROM cat_categories WHERE macro_id = 1)
Demo on SQLFiddle

MySQL JOIN, WHERE and IF issue

i have table of members
table members :
pid| id | name
1 | id01 | jenny
2 | id02 | kain
3 | id03 | alex
and have another table members_opt
table members_opt
pid | members_id | category
1 | id01 | cat
2 | id01 | dog
3 | id02 | dog
4 | id03 | NULL
now i use below SQL query
SELECT * FROM members a JOIN
(SELECT members_id, max(category) as category FROM members_opt GROUP BY members_id) b
ON a.id = b.members_id
But this SQL Query not catch "id03"'s data because "id03"'s members_opt.category is NULL
I want this result
result :
id | name | category
id01 | jenny | cat
id02 | kain | dog
id03 | alex | NULL
(the result now showed double name, double id value.)
How can i use SQL query?
You can try this -
SELECT * FROM members a JOIN
(SELECT members_id, max(CASE WHEN category IS NULL THEN 0) as category FROM members_opt GROUP BY members_id) b
ON a.id = b.members_id
Use the below query to get your desired output -
SELECT a.id, a.name, b.category FROM members a INNER JOIN
(SELECT members_id, category FROM members_opt GROUP BY members_id) b
ON a.id = b.members_id
Just change JOIN to LEFT JOIN :
SELECT a.id, a.name, b.category
FROM members a
LEFT JOIN (
SELECT members_id, max(category) as category
FROM members_opt GROUP BY members_id) b
ON a.id = b.members_id
and if you want 'cat' for 'jenny', you should use aggregation function min.

sql query combine two queries into one with empty rows

This is my sql table structure:
Table1: details
|--id--|--id_user--|--price--|
| 1 | 1 | 10 |
| 2 | 2 | 15 |
| 3 | 1 | 25 |
| 4 | 3 | 30 |
| 5 | 3 | 7 |
------------------------------
Table2: users
|--id--|--id_country--|
| 1 | 1 |
| 2 | 2 |
| 3 | 0 |
-----------------------
Table3: country
|--id--|--country--|
| 1 | France |
| 2 | Italy |
--------------------
What I need is to get the SUM of price by country:
SELECT c.country, SUM(d.price) AS price
FROM details d
INNER JOIN users u ON u.id = d.id_user
INNER JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
I get this:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
-----------------------
BUT I'd need to get this:
|--country--|--price--|
| France | 35 |
| Italy | 15 |
| Undefined | 37 |
-----------------------
where undefined would be if id_country=0. (I can't add to country table the id=0 or id=undefined, it will messed up other things). Right now I'm achieving this by two separate queries, the second one is:
SELECT SUM(d.price) as price
FROM details d
INNER JOIN users u ON u.id = d.id_user AND u.id_country=0
GROUP BY u.id_country
I'm thinking if... is it possible to do this in one query?
You need to use left join in this case:
SELECT c.country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
If you use INNER JOIN, you will only get results that exists in both tables.
To replace NULL with Undefined use:
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
One way to sort to get Undefined last is to add a Sortfield
SELECT A.Country,A.Price FROM (
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price, IFNULL(c.Country,'ZZZZZZZZ') AS Sort
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
) A
ORDER BY A.Sort
Edit: ORDER BY suggested in comments
SELECT IFNULL(c.country,'Undefined') AS Country, SUM(d.price) AS price
FROM details d
LEFT JOIN users u ON u.id = d.id_user
LEFT JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country IS NULL, c.country
Try below query.
SELECT
CASE
WHEN c.country is NULL THEN 'Undefined'
ELSE c.country
END as country
, SUM(d.price) AS price
FROM users u
left JOIN details d ON u.id = d.id_user
left JOIN country c ON c.id = u.id_country
GROUP BY c.country
ORDER BY c.country
For Demo :
SqlfiddlE Demo :
Please let us know if you have any que.

MySQL: SELECT from three tables?

I have problems with a MySQL query with three tables. I would like to search for a name and get all (even better only the first one) phonenumber and email. Here are my tables:
Table 1, contact
==========
id | name
==========
1 | stefan
2 | michael
3 | andy
4 | bob
Table 2, phone
==============================
id | contact_id | phonenumber
==============================
1 | 1 | +1 434 434232
2 | 1 | +1 434 24234
3 | 2 | +1 89234
4 | 4 | +1 345345
5 | 4 | +1 434 7567567
Table 3, email
===============================
id | contact_id | emailaddress
===============================
1 | 1 | stefan#home.com
2 | 1 | stefan#work.com
3 | 1 | stefan#mars.com
4 | 4 | bob#anywhere.com
5 | 2 | michael#nothing.com
And this is my query, which seams to send MySQL to nirvana:
SELECT c.name, p.phonenumber, e.emailaddress
FROM contact AS c
JOIN phonenumber AS p ON c.id = p.contact_id
JOIN email AS e ON c.id = e.contact_id
WHERE c.name = 'michael'
When I do only one join this works fine as:
SELECT c.name, p.phonenumber
FROM contact AS c
JOIN phonenumber AS p ON c.id = p.contact_id
WHERE c.name = 'michael'
Any ideas?
Thanks
Mike
Try this:
SELECT c.name, p.phonenumber, e.emailaddress
FROM name_of_your_schema.contact AS c
JOIN name_of_your_schema.phone AS p ON c.id = p.contact_id
JOIN name_of_your_schema.email AS e ON c.id = e.contact_id
WHERE c.name = 'stefan'
LIMIT 1;
Tom L.
Try
SELECT c.name, p.phonenumber, e.emailaddress
FROM contact c
INNER JOIN phone p ON c.id = p.contact_id
INNER JOIN email e ON p.contact_id = e.contact_id
WHERE c.name = 'michael'
To get just one result per contact, you might use aggregation in a bit unorthodox way. I modified #Emanuel Saringan's query:
SELECT c.name, min(p.phonenumber), min(e.emailaddress)
FROM contact c
left JOIN phone p ON c.id = p.contact_id
left JOIN emailaddress e ON c.id = e.contact_id
WHERE c.name = 'michael'
GROUP BY c.id
See it work here:
http://sqlfiddle.com/#!2/6a8700/2

How to count the number of people who choose a particular location?

i need help in select sql statement.
in my mysql database:
location table
serialID(AI)|locations | telephone | address
---------------------------------------------
1 | A
2 | B
3 | C
4 | D
users table
userID | location chosen
-------------------------
1 | A
2 | B
3 | B
I want to count the number of people who choose a particular location and display in the table. So if this particular location have more users choosen as their favourite location, it will move up to the first row. May I know how can I do this?
something like this when it populate into dynamic table ->
location | address | telephone | user's favourable
B | - | - | 2
A | - | - | 1
C | - | - | 0
D | - | - | 0
You could just do a query like this:
SELECT l.locations, l.telephone, l.address, COUNT (u.userID) as `location_count`
FROM location AS l
LEFT OUTER JOIN users AS u on l.locations = u.location_chosen
GROUP BY l.locations
ORDER BY `location_count` DESC
Try something like this:
SELECT l.location, l.address, l.telephone, COUNT(u.userID) AS [users favourable]
FROM location l
LEFT JOIN
users u
ON l.location = u.locationchosen
GROUP BY l.location, l.address, l.telephone
SELECT loc.*, countResult.usersFavourable
FROM location loc
LEFT JOIN
(
SELECT locationChoosen, COUNT(*) `usersFavourable`
FROM users
GROUP BY locationChoosen
) countResult ON loc.locations = countResult.locationChoosen
ORDER BY countResult.usersFavourable DESC, loc.locations
use this:
select count(userId) count,locations,address,telephone
from Table1 Left join Table2
on Table1.locations = Table2.location
group by locations order by count desc ;
see here.. link
SELECT LocationChosen, Count(*) FROM usersTable GROUP BY LocationChosen