SELECT Query with COUNT and INNER JOIN - mysql

I am facing some difficulties since I'm not very experienced in SQL. So i have the tables:
----------------- -------------------
| membership_info | | client_info |
----------------- -------------------
| ID (PK) | | client_id (FK) |
| Name | | membership_id (FK)|
| Price | | value_paid |
----------------- -------------------
The membership_info and client_info has the values like:
-------------------------- ----------------------------------------
| ID | Name | Price | | client_id | membership_id | value_paid |
-------------------------- ----------------------------------------
| 1 | Daily | 30 | | 24 | 2 | 80 |
| 2 | Weekly | 80 | | 25 | 2 | 80 |
| 3 | Monthly | 100 | | 26 | 3 | 100 |
-------------------------- ----------------------------------------
Now the problem that I'm facing is that i cannot figure out how to query a result looking like this:
-------------------------------------
| Membership Name | Membership Count |
-------------------------------------
| Weekly | 2 |
| Monthly | 1 |
-------------------------------------
Please help!

select name, count(*)
from client_info c
inner join membership_info m on c.membership_id = m.id
group by name

Related

Find a Customer that buys only specific products & did not buy any other products in codeigniter query

customers table
| id | name | email |
| 1 | richa| richa#gmail.com |``
| 2 | sam | sam#gmail.com |
| 3 | hella| hella#gmail.com |
orders table
| id | customer_id |
| 101 | 1 |
| 102 | 2 |
| 103 | 3 |
order_product table
| id | order_id | product_id |
| | 101 | 1 |
| | 102 | 1 |
| | 103 | 2 |
products table
| id | product_name |
| 1 | Mobile |
| 2 | AC |
| 3 | Fridge |
These are tables, I want to display customers who buy only one type of products(can be multiple) but did not buy any other products.
$resultArr = $this->db->table('customers')``
->join('orders', 'orders.customer_id = customers.id')
->join('order_products', 'order_products.order_id = orders.id')
->select('customers.id, customers.name, customers.email');
->groupBy('customers.id');
->where('order_products.product_id', > 0);
return $resultArr;
I added this query but i did not get required data. can anyone give any idea or explain me if i did any mistake in it let me know. Thanks in advance.

When i add where in query it's now showing count 0

I'm having a problem with a query is not showing COUNT 0 when i'm adding where clause.
I have two tables "Parking" & "Active_Parking". I want to get COUNT of active parkings per id_parking that datetime_out is >= then current time to compare with parking_space.
Parking
| id_parking | parking_name | parking_location | parking_space |
| -------------- | ------------ | ---------------- | ------------ |
| 1 | ABC | 1st street | 35 |
| 1 | ABC | 2nd street | 50 |
| 1 | ABC | 3rd street | 150 |
Active Parking
| id_active_parking | id_parking | car_plates | datetime_IN |
| ------------------- | ----------- | ---------- | -------------------- |
| 1 | 1 | 00-XXX-00 | 2018-12-16 14:00:00 |
| 2 | 1 | 00-XXX-00 | 2018-12-16 14:21:34 |
| 3 | 2 | 00-XXX-00 | 2018-12-16 21:35:00 |
| 4 | 2 | 00-XXX-00 | 2018-12-16 22:00:00 |
| datetime_OUT |
| -------------------- |
| 2018-12-16 15:00:00 |
| 2018-12-16 15:21:34 |
| 2018-12-16 22:35:00 |
| 2018-12-16 23:00:00 |
Query:
SELECT
p.id_parking,
p.parking_name,
p.parking_location,
p.parking_space,
COUNT(ap.id_parking) AS Active
FROM
parking p
LEFT JOIN active_parking ap
ON ap.id_parking = p.id_parking
WHERE
ap.datetime_OUT >= '2018-12-16 22:16:00'
GROUP BY p.id_parking
Query Result:
| id_parking | COUNT(ap.id_parking) |
| -------------- | -------------------- |
| 2 | 2 |
Is not showing id_parking 1 and 3 COUNT = 0
What is the reason to use LEFT JOIN in this case? Remove group by + count and check the result. I believe you should use INNER JOIN in this case. You can read about differences in many places, including wiki
If you really need all list of p.id_parking, you should move your WHERE clause to ON:
LEFT JOIN active_parking ap ON (
ap.id_parking = p.id_parking
AND ap.datetime_OUT >= '2018-12-16 22:16:00'
)
Then you should have proper count of active parkings.

Get quantity per product in each order using MySQL

I have 3 tables, order, products, and orders_products and I'm trying to find out how many of each product was bought in each order. Is it possible to get all information in a single query?
My current query doesn't seem to work, whereas the product_id comes out as all the same.
SELECT orders.order_id, orders.username, COUNT( DISTINCT op.product_id ) product_id, SUM( op.quantity ) quantity
FROM `orders`
JOIN orders_products op ON op.order_id = orders.order_id
GROUP BY product_id, orders.order_id ORDER BY order_id, product_id
Which results in:
_______________________________________________
| order_id | username | product_id | quantity |
-----------------------------------------------
| 1 | bill | 1 | 3 |
-----------------------------------------------
| 1 | bill | 1 | 2 |
-----------------------------------------------
| 1 | bill | 1 | 5 |
-----------------------------------------------
| 2 | sally | 1 | 2 |
-----------------------------------------------
| 3 | jeff | 1 | 6 |
-----------------------------------------------
| 3 | jeff | 1 | 7 |
-----------------------------------------------
You can see the problem above in the product_id column which is always set to 1.
I'm trying to get something like this:
_______________________________________________
| order_id | username | product_id | quantity |
-----------------------------------------------
| 1 | bill | 1 | 5 |
-----------------------------------------------
| 1 | bill | 2 | 3 |
-----------------------------------------------
| 1 | bill | 3 | 2 |
-----------------------------------------------
| 2 | sally | 1 | 2 |
-----------------------------------------------
| 3 | jeff | 1 | 6 |
-----------------------------------------------
| 3 | jeff | 2 | 7 |
-----------------------------------------------
My tables:
-- Orders
_______________________
| order_id | username |
-----------------------
| 1 | bill |
-----------------------
| 2 | sally |
-----------------------
| 3 | jeff |
-----------------------
-- Products
___________________
| id | product |
-------------------
| 1 | Table |
-------------------
| 2 | Chair |
-------------------
| 3 | Mouse |
-------------------
-- Order Products
___________________________________________
| id | order_id | product_id | quantity |
-------------------------------------------
| 1 | 1 | 1 | 5 |
-------------------------------------------
| 2 | 1 | 2 | 3 |
-------------------------------------------
| 3 | 1 | 3 | 2 |
-------------------------------------------
| 4 | 2 | 1 | 2 |
-------------------------------------------
| 5 | 3 | 1 | 6 |
-------------------------------------------
| 6 | 3 | 2 | 7 |
-------------------------------------------
I think the query you want is:
SELECT o.order_id, o.username, op.product_id, SUM( op.quantity ) as quantity
FROM `orders` o JOIN
orders_products op
ON op.order_id = o.order_id
GROUP BY op.product_id, o.order_id
ORDER BY o.order_id, op.product_id;
In general, you do want all the columns in the GROUP BY in the SELECT. But (in general) they shouldn't be arguments to aggregation functions such as COUNT().
You can see the problem above in the product_id column which is always
set to 1
I think you are bit confused here, that's the data present in Order Products table for product_id column but in your query what you are trying to get is count of data COUNT( DISTINCT op.product_id ) product_id and since the count is 1, the result is showing the same.

Complex MySQL Query for Many-to-Many

I have searched and gone through the available topics similar to mine. But, failed to find that satisfies my requirements. Hence, posting it here.
I have four tables as follows:
"Organization" table:
--------------------------------
| org_id | org_name |
| 1 | A |
| 2 | B |
| 3 | C |
"Members" table:
----------------------------------------------
| mem_id | mem_name | org_id |
| 1 | mem1 | 1 |
| 2 | mem2 | 1 |
| 3 | mem3 | 2 |
| 4 | mem4 | 3 |
"Resource" table:
--------------------------------
| res_id | res_name |
| 1 | resource1 |
| 2 | resource2 |
| 3 | resource3 |
| 4 | resource4 |
"member-resource" table:
--------------------------------------------
| sl_no | mem_id | res_id |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 4 | 3 |
| 5 | 3 | 4 |
| 6 | 2 | 3 |
| 7 | 4 | 3 |
I want to find out the total number of distinct resources according to organizations. Expected output is as follows:
| org_name | Total Resources |
| A | 3 |
| B | 1 |
| C | 1 |
I also want to find out the total number of shared resources according to organizations. Expected output is as follows:
| org_name | Shared Resources |
| A | 1 |
| B | 0 |
| C | 1 |
Any help in this regard will highly be appreciated.
Regards.
It is much simpler than you think, particularly because you don't even need the resource table:
SELECT o.org_name, COUNT(DISTINCT mr.res_id) TotalResources
FROM member_resource mr
JOIN members m ON mr.mem_id = m.mem_id
JOIN organization o ON m.org_id = o.org_id
GROUP BY o.org_id
Output:
| ORG_NAME | TOTALRESOURCES |
|----------|----------------|
| A | 3 |
| B | 1 |
| C | 1 |
Fiddle here.
Try this query below.
SELECT org_name, COUNT(DISTINCT res_id)
FROM organization, members, member-resource
WHERE members.mem_id = member-resource.mem_id
AND organization.org_id = members.org_id
GROUP BY org_id, org_name

Selecting users id based on affiliation to group

I have a database, where there are groups that have many users (1:N). Those two tables are designed to have a unique ID for every group and unique ID for every user. But now I came to a problem that I need to SELECT an ID of a group and also an ID of a user within that group (which is different from his real database ID). Is there some way to SELECT these sub-IDs in MySQL without actually changing users table structure?
What my current table structure looks like:
-----------------
| GROUPS |
=================
| ID PK AUTO_INC|
| NAME |
| DESCRIPTION |
| ...other |
| non-related |
| columns |
-----------------
------------------
| USERS |
==================
| ID PK AUTO_INC |
| NAME |
| GROUP |
| AGE |
|...other |
| non-related |
| columns |
------------------
EDIT: What I would like looks like this:
GROUPS
----------------------------------
| ID | Name | Description | ... |
==================================
| 1 | A | First one | ... |
| 2 | B | Second one | ... |
| 3 | C | Third one | ... |
----------------------------------
USERS
--------------------------------------
| ID | Name | Group | Age | ... |
======================================
| 1 | John | 1 | 35 | ... |
| 2 | Adam | 1 | 22 | ... |
| 3 | Bob | 2 | 18 | ... |
| 4 | Jane | 1 | 38 | ... |
| 5 | Emma | 2 | 56 | ... |
| 6 | Aaron | 3 | 26 | ... |
| 7 | Alice | 2 | 48 | ... |
--------------------------------------
And as a result I would like to get:
-----------------------------------
| GID | UID| Name | Age | ... |
===================================
| 1 | 1 | John | 35 | ... |
| 1 | 2 | Adam | 22 | ... |
| 1 | 3 | Jane | 38 | ... |
| 2 | 1 | Bob | 18 | ... |
| 2 | 2 | Emma | 56 | ... |
| 2 | 3 | Alice | 48 | ... |
| 3 | 1 | Aaron | 26 | ... |
-----------------------------------
I hope now it will make sense.
Thanks in advance.
The only way I know how to do this is with variables
select
t.id,
t.name,
t.group,
t.rank as newid
from (
select
u.id,
u.name,
u.group,
If(#group <> u.`Group`, #rownum := 1, #rownum := #rownum + 1) AS rank,
#group := u.`Group`
from
Users u
cross join (
select
#rownum := NULL,
#group := 0
) as r
order by
u.group,
u.id
) as t
order by
t.group,
t.id;
This method isn't guaranteed to work, but in practice it seems to.
Example SQLFiddle