SELECT and COUNT in one query from two tables with mySQL - mysql

Here my tables structure:
___Rooms
|--------|-------------|------------|
| ROO_Id | ROO_HotelId | ROO_Status |
|--------|-------------|------------|
| 1 | 1 | active |
| 2 | 1 | active |
| 3 | 1 | inactive |
|--------|-------------|------------|
___Subscriptions
|-------------|-----------|
| SUB_HotelId | SUB_Limit |
|-------------|-----------|
| 1 | 24 |
|-------------|-----------|
I want to select SUB_Limit and count the number of rooms (only the active one).
So the query should returns me something like this:
|-----------|------------|
| SUB_Limit | ROO_Number |
|-----------|------------|
| 24 | 2 |
|-----------|------------|
Why this query do not return me the desired output please ?
SELECT
SUB_Limit,
COUNT(ROO_Id) AS ROO_Number
FROM ___Rooms
LEFT JOIN ___Subscriptions
ON ___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
WHERE ROO_Status = 'active'
AND SUB_HotelId = 1
AND ROO_HotelId = 1
Actually, it gave me:
|-----------|------------|
| SUB_Limit | ROO_Number |
|-----------|------------|
| NULL | 0 |
|-----------|------------|

Try this below query once
SELECT
SUB_Limit, COUNT(ROO_Id) AS ROO_Number FROM
___rooms r,___subscriptions s
WHERE r.ROO_HotelId=s.SUB_HotelId AND ROO_Status='active'

Try below query:
SELECT s.sub_limit, count(ROO_Id)
FROM ___Rooms r
INNER JOIN ___Subscription s ON (s.SUB_HotelId = r.ROO_HotelId)
WHERE s.SUB_HotelId = 1
and r.ROO_STATUS = 'active'

You forgot GROUP BY
SELECT
S.SUB_Limit,
COUNT(*) AS ROO_Number
FROM ___Rooms AS R
RIGHT JOIN ___Subscriptions AS S
ON R.ROO_HotelId = S.SUB_HotelId
WHERE R.ROO_Status = 'active'
AND S.SUB_HotelId = 1
GROUP BY ROO_HotelId
UPD: group by is not necessary as we need only the number of all lines. Also RIGHT JOIN could not be available for your particular MySQL engine (unlike LEFT JOIN or INNER JOIN), so you would better use UNION constructions, to catch zero intersections with main table if I'm not mistaken.

Related

Is there a way to select data from one column in SQL table to get table with multiple columns?

So I have two SQL tables: one with id and in the other is meta value and meta_key. I joined them so it looks something like this:
+------+------------+----------+
| id | meta_value | meta_key |
+------+------------+----------+
| 1544 | product1 | 1 |
| 1544 | 2 | 2 |
| 1545 | product2 | 1 |
| 1545 | 5 | 2 |
| 1546 | product3 | 1 |
| 1546 | 10 | 2 |
+------+------------+----------+
And I want to get a query that would show me a table like this:
+------+------------+------------+
| id | meta_value | meta_value |
+------+------------+------------+
| 1544 | product1 | 2 |
| 1545 | product2 | 5 |
| 1546 | product3 | 10 |
+------+------------+------------+
The SQL query for first table looks like this:
SELECT
wprq_gf_entry.id,
wprq_gf_entry_meta.meta_value,
wprq_gf_entry_meta.meta_key
FROM
wprq_gf_entry
INNER JOIN wprq_gf_entry_meta ON wprq_gf_entry.id = wprq_gf_entry_meta.entry_id
WHERE
wprq_gf_entry_meta.form_id = 6
Is there a way to do this? ... Thank you!
You can use JOIN, but you need two of them:
SELECT e.*, m1.meta_value, m2.meta_value
FROM wprq_gf_entry e JOIN
wprq_gf_entry_meta m1
ON e.id = m1.entry_id AND m1.meta_key = 1 JOIN
wprq_gf_entry_meta m2
ON e.id = m2.entry_id AND m2.meta_key = 2;
You can use the table you created, let's call it joined_table.
With joined_table as(
SELECT
wprq_gf_entry.id,
wprq_gf_entry_meta.meta_value,
wprq_gf_entry_meta.meta_key
FROM wprq_gf_entry
INNER JOIN wprq_gf_entry_meta ON wprq_gf_entry.id
= wprq_gf_entry_meta.entry_id
WHERE wprq_gf_entry_meta.form_id = 6
)
Were dividing it into two tables - one with meta-key = 1 and the other with meta-key = 2.
Then, we are joining them
Select jt.id, jt.meta_value as meta_value_1,
jt2.meta_value as meta_value_2
From joined_table jt
Join joined_table jt2
On jt.id = jt2.id
And jt2.meta_key = 2
Where jt.meta_key = 1

Join table in mySQL return me NULL if joined table don't contain row

Here my tables structure:
___Rooms
|--------|-------------|
| ROO_Id | ROO_HotelId |
|--------|-------------|
| 1 | ABC123 |
| 2 | ABC123 |
| 3 | ABC123 |
|--------|-------------|
___Subscriptions
|-------------|-----------|
| SUB_HotelId | SUB_Limit |
|-------------|-----------|
| ABC123 | 19 |
| XYZ987 | 23 |
|-------------|-----------|
This query work when ___Rooms has a rows with desired HotelId.
SELECT
COUNT(ROO_Id) AS SUB_RoomNumber,
SUB_Limit
FROM ___Subscriptions
LEFT JOIN ___Rooms
ON ___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
WHERE SUB_HotelId = 'ABC123'
AND ROO_HotelId = 'ABC123'
|----------------|-----------|
| SUB_RoomNumber | SUB_Limit |
|----------------|-----------|
| 3 | 19 |
|----------------|-----------|
For hotel XYZ987, this hotel do not have actually room in ___Rooms, and the query return me NULL for SUB_Limit :
|----------------|-----------|
| SUB_RoomNumber | SUB_Limit |
|----------------|-----------|
| 0 | NULL |
|----------------|-----------|
Why please ?
Do not check for ROO_HotelId = 'XYZ987', inside the Where condition. If there is no matching ROO_HotelId in the __Rooms table, no data would appear (if using Where).
Basically, once you have done Join between the tables, ON HotelId, you only need to put Where condition for one of the tables. In the case of Inner Join, either of the tables can be used. However, in the case of Left join, you need to use the left table.
Use the following:
SELECT
COUNT(ROO_Id) AS SUB_RoomNumber,
SUB_Limit
FROM ___Subscriptions
LEFT JOIN ___Rooms
ON ___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
WHERE SUB_HotelId = 'XYZ987'

COUNT and SELECT into the same query in mySQL

Form my two tables, I want to select SUB_Limit and count the number of rooms (only the active one).
So the query should returns me something like this:
|-----------|------------|-------------|
| SUB_Limit | ROO_Number | ROO_HotelId |
|-----------|------------|-------------|
| 10 | 0 | 1 |
| 15 | 3 | 2 |
| 5 | 2 | 3 |
| 25 | 0 | 4 |
|-----------|------------|-------------|
Why this query do not return me the desired output please ?
SELECT
ROO_HotelId,
SUB_Limit,
COUNT(ROO_Id) AS ROO_Number
FROM ___Rooms
LEFT JOIN ___Subscriptions
ON ___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
WHERE ROO_Status = 'active'
AND SUB_HotelId = 1
AND ROO_HotelId = 1
Actually, it gave me:
|-----------|------------|
| SUB_Limit | ROO_Number |
|-----------|------------|
| 15 | 3 |
| 5 | 2 |
|-----------|------------|
So I haven't the ___Subscriptions with no rooms.
Here the SQL Fiddle for help.
Thanks in advance.
The query below gives you the result you want.
SELECT
SUB_HotelId,
SUB_Limit,
COUNT(ROO_Id) AS ROO_Number
FROM ___Subscriptions
LEFT JOIN ___Rooms ON
___Rooms.ROO_HotelId = ___Subscriptions.SUB_HotelId
WHERE ROO_Status = 'active' or ROO_Status is null
GROUP BY SUB_HotelId
You need to check for ROO_Status = 'active' or NULL because if the subscription is not linked to a room, there will be no value for ROO_Status. Also, you need to group on SUB_HotelId, because ROO_HotelId will also be null if there is no room to join the subscription to.
Link to fiddle: http://sqlfiddle.com/#!9/c6920c/35

Sum is not done if joined table is empty with MySQL

I have the following tables structure and trying to make a report from these:
___BillableDatas
|--------|------------|---------|--------------|------------|
| BIL_Id | BIL_Date |BIL_Rate | BIL_Quantity | BIL_Status |
|--------|------------|---------|--------------|------------|
| 1 | 2018-03-01 | 105 | 1 | charged |
| 2 | 2018-03-01 | 15 | 2 | notcharged |
| 3 | 2018-03-01 | 5 | 1 | notcharged |
|--------|------------|---------|--------------|------------|
___SalesTaxes
|--------|--------------|------------|
| STX_Id | STX_TaxeName | STX_Amount |
|--------|--------------|------------|
| 8 | Tax 1 | 5.000 |
| 9 | Tax 2 | 15.000 |
|--------|--------------|------------|
STX_Amount is a percentage.
___ApplicableTaxes
|-----------|-----------|
| ATX_BILId | ATX_STXId |
|-----------|-----------|
| 1 | 8 |
| 1 | 9 |
|-----------|-----------|
ATX_BILId is the item ID link with ___BillableDatas.
ATX_STXId is the tax ID link with ___SalesTaxes.
I need to get to sum of the items per day
- without tax
- with tax
So mething like this:
|------------------|---------------|------------|
| BIL_RateNonTaxed | BIL_RateTaxed | BIL_Status |
|------------------|---------------|------------|
| 105.00 | 126.00 | charged | <- Taxes #8, #9 applicable
| 35.00 | 35.00 | notcharged | <- No taxes here
|------------------|---------------|------------|
Explications on the totals:
105 = 105*1 -- (total of the charged item multiply by the quantity)
35 = (15*2)+5 -- (total of the notcharged items multiply by the quantity)
126.00 = 105+(105*(5+15)/100)
35.00 = as no taxe, put the non taxed value.
My last try was this one:
SELECT BIL_Status
, SUM(BIL_Rate*BIL_Quantity) BIL_RateNonTaxed
, IFNULL(SUM((BIL_Rate*BIL_Quantity)+(BIL_Rate*BIL_Quantity*total_sales_tax/100)), SUM(BIL_Rate*BIL_Quantity)) BIL_RateTaxed
FROM
( SELECT b.*
, SUM(t.STX_Amount) total_sales_tax
FROM ___BillableDatas b
LEFT JOIN ___ApplicableTaxes bt
ON bt.ATX_BILId = b.BIL_Id
LEFT JOIN ___SalesTaxes t
ON t.STX_Id = bt.ATX_STXId
GROUP
BY ATX_BILId
) x
GROUP
BY BIL_Status
This query works just when each item has a linked taxe (case of my item #1). When item has no linked taxes (item #2 and #3), the sum is not made.
Please see this SQLFiddle to help you if needed:
http://sqlfiddle.com/#!9/433a3f/2
The only one error with the link is I should have 35 and not 30.
Thanks.
The subquery was grouping by the wrong thing. You are grouping by ATX_BILId, but I think you really wanted to get all the unique billable data bill_ids. At least the following query returns what you expected. The only difference is changing "GROUP BY ATX_BILId" to "GROUP BY BIL_Id"
SELECT BIL_Status
, SUM(BIL_Rate*BIL_Quantity) BIL_RateNonTaxed
, IFNULL(SUM((BIL_Rate*BIL_Quantity)+(BIL_Rate*BIL_Quantity*total_sales_tax/100)), SUM(BIL_Rate*BIL_Quantity)) BIL_RateTaxed
FROM
( SELECT b.*
, SUM(t.STX_Amount) total_sales_tax
FROM ___BillableDatas b
LEFT JOIN ___ApplicableTaxes bt
ON bt.ATX_BILId = b.BIL_Id
LEFT JOIN ___SalesTaxes t
ON t.STX_Id = bt.ATX_STXId
GROUP
BY BIL_Id
) x
GROUP
BY BIL_Status
Link to SQL Fiddle
In general, when you are troubleshooting this type of query, the first thing to do is examine the returned rows without the group bys. It becomes easier to see the problem when you run the following query.
SELECT BIL_Status,
BIL_Rate,
BIL_Quantity,
total_sales_tax
FROM
( SELECT b.*
, SUM(t.STX_Amount) total_sales_tax
FROM ___BillableDatas b
LEFT JOIN ___ApplicableTaxes bt
ON bt.ATX_BILId = b.BIL_Id
LEFT JOIN ___SalesTaxes t
ON t.STX_Id = bt.ATX_STXId
GROUP
BY ATX_BILId
) x

MySQL Join and Default

I'm still very new to SQL queries and can't quite figure this one out.
I have two tables, one table I'm running a general SELECT ... WHERE, super easy SQL statement.
Ex:
SELECT * from maindata where somedata4 LIKE "%data4.%"
This gives me back a list of all 6 entries below, however I want an additional column to show me if the current userdata.userId has a matching row and to include the amount column of that. If it doesn't have that row to default to a value of 0.
Table: maindata
id | somedata | somedata2 | somedata3 | somedata4
_________________________________________________
1 | data1.1 | data2.1 | data3.1 | data4.1
2 | data1.2 | data2.2 | data3.2 | data4.2
3 | data1.3 | data2.3 | data3.3 | data4.3
4 | data1.4 | data2.4 | data3.4 | data4.4
5 | data1.5 | data2.5 | data3.5 | data4.5
6 | data1.6 | data2.6 | data3.6 | data4.6
Table: userdata
id | itemId | amount | userId
_____________________________
1 | 6 | 4 | 1
2 | 4 | 4 | 26
3 | 4 | 2 | 1
It should search table maindata for WHERE somedata4 LIKE "%data4.%" and on each of those entries look in table userdata for userdata.amount with maindata.id = userdata.itemId WHERE maindata.userId = 1
Here's what I currently have for SQL
SELECT m.*, IFNULL(u.amount,0)
from maindata m
LEFT OUTER JOIN userdata u ON m.id = u.itemId
WHERE m.somedata4 LIKE "%data4.%"
What I'm missing is the filtering of only amounts from userdata.userId = 1, I want the entire list to show as it is in that query.
Expected Results:
id | somedata | somedata2 | somedata3 | somedata4 | amount
__________________________________________________________
1 | data1.1 | data2.1 | data3.1 | data4.1 | 0
2 | data1.2 | data2.2 | data3.2 | data4.2 | 0
3 | data1.3 | data2.3 | data3.3 | data4.3 | 0
4 | data1.4 | data2.4 | data3.4 | data4.4 | 4
5 | data1.5 | data2.5 | data3.5 | data4.5 | 0
6 | data1.6 | data2.6 | data3.6 | data4.6 | 2
SELECT m.*, IFNULL(u.amount,0) from maindata m LEFT OUTER JOIN
userdata u ON m.id = u.itemId WHERE m.userId = 1
Here is the SQL Query I was looking for (I think):
SELECT m.*, IFNULL(u.amount,0) AS "Amount"
FROM maindata m
LEFT OUTER JOIN userdata u ON m.id = u.itemId AND userid = 1
WHERE m.somedata4 LIKE "%data4.%"
It's giving me the desired results listed above, I just don't know if it's the most efficient way of handling this request.
SQLFiddle Here
I tried this solution but i am not sure if this is what you are looking for. Let me know.
-------EDIT--------
Now I'm sure about what you are looking for. I had just a couple of minutes so I didn't really optimized the code, but this seems to work except for the order of the fields, that can't be really modified since we're operating in two different sets of results.
By the way, this is the query
SELECT m.*, '0' as amount
from maindata m
left outer JOIN userdata u ON m.id = u.itemId
where (u.userid is null) and m.somedata4 LIKE '%data4.%'
UNION
SELECT m.*, u.amount
from maindata m
inner JOIN userdata u ON m.id = u.itemId
where u.userid = 1 and m.somedata4 LIKE '%data4.%'
and this is the updated fiddle
Hope this helps.