let say I have the following table:
#hotel_id #room_id #price
3 4 50.00
3 5 45.00
3 6 50.00
4 5 45.00
4 7 50.00
4 8 45.00
5 4 45.00
5 8 50.00
5 9 45.00
what query must I execute in order to get the number of unique #hotel_id - in this case it is 3,4,5 = 3 unique ids
May sound simple , but... :) thank you in advance
########### my query
select
Count(Distinct a.id),
rta.room_type_id,
IF(SUM(price = 0), 0, SUM(price))
from
adverts a,
rooms_to_adverts rta,
room_types rt,
prices_adverts pa
where
a.town = 'Sofia' and a.id = pa.advert_id
and rta.room_type_id = rt.id
and pa.room_type_id = rta.room_type_id
and rta.advert_id = a.id
and (pa.date >= '2013-09-20'
AND pa.date < '2013-09-23')
and rt.occupants >= '1'
GROUP BY a.id , rta.room_type_id
order by a.id , rt.occupants ASC
this query ouputs this
LOOKS like it is not so simple :)
Part of what you already have is the answer:
SELECT
COUNT(DISTINCT adverts.id)
FROM adverts
Or is there a complication that you haven't told us about?
Related
Currently I am honestly at loss what I am doing wrong. It is a rather simple query I think.
Tables:
operations:
id processedon clientid
1 2018-01-01 9
2 2018-03-16 9
3 2018-04-21 9
4 2018-04-20 9
5 2018-05-09 9
items:
id operation_id quantity unitprice
1 1 10 2
2 1 5 3
3 2 20 4
4 3 10 2
5 4 8 4
6 4 10 4
7 5 2 2
The expected result of the operation/query is:
month total_value
1 35
3 80
4 92
5 4
That is quantity * unitprice based. For some reason, it only returns month=4
SELECT
month(`operations`.`processedon`) AS `month`,
SUM((`items`.`quantity` * `items`.`unitprice`)) AS `total_value`
FROM `items`
INNER JOIN `operations` ON (`items`.`operation_id` = `operations`.`id`)
GROUP BY 'month'
ORDER BY 'month'
According to the info provided the join should be
INNER JOIN operations ON items.operation_id = operations.id
Eg
SELECT
month(`operations`.`processedon`) AS `month`,
SUM((`items`.`quantity` * `items`.`unitprice`)) AS `total_value`
FROM `items`
INNER JOIN `operations` ON `items`.`operation_id` = `operations`.`id`
GROUP BY month(`operations`.`processedon`)
ORDER BY `month`
There is no efficiency gain by using a column alias in the group by clause, I prefer to avoid using them except perhaps in the order by clause.
The following query will give you the required answer
SELECT
month(`operations`.`processedon`) AS `month`,
SUM((`items`.`quantity` * `items`.`unitprice`)) AS `total_value`
FROM items
INNER JOIN operations ON (items.operation_id = operations.id)
GROUP BY month(operations.processedon)
ORDER BY month(operations.processedon)
You need to specify month correctly since it is not an existing column.
You'll get the following result
month total_value
1 35
3 80
4 92
5 4
I am struggling at writing a query to get data from a table like this:
id food_id ingre_id
1 1 13
2 1 9
3 2 13
4 3 5
5 4 9
6 4 10
7 5 5
Assume in that table, each food only have 1 or 2 ingre ids. Then I want to have a table like this:
item_id ingre1_id ingre2_id
1 13 9
2 13 null //any food that have 1 ingre then set ingre2_id to null
3 5 null
4 9 10
5 5 null
Please suggest me a query to do such conversion. Thank you!
You can use aggregation. If you don't care about the ordering within a row:
select food_id, min(ingred_id) as ingred1_id,
(case when min(ingred_id) <> max(ingred_id) then max(ingred_id) end) as ingred2_id
from t
group by food_id;
Note: This use of min()/max() works specifically because you have two values. If you have more values, then ask another question with appropriate data.
This should produce what you asked for:
SELECT
a.`food_id` as `item_id`,
a.`ingre_id` as `ingre1_id`,
b.`ingre_id` as `ingre2_id`
FROM `food` a
LEFT JOIN `food` b
ON a.`id` <> b.`id` AND a.`food_id` = b.`food_id`
WHERE a.`id` < b.`id` OR b.`id` IS NULL
GROUP BY a.`food_id`
My table is similar to the one below. I would like to select records where city and town matches and code or area has repetition. In this case rows the result should be all rows except the ones with id 3 and 5. Thanks for looking at this
city town id code1 code2 code3 code4 area1 area2 area3 area4
----------------------------------------------------------------------------------
dublin town1 1 1 2 3 5 1 2 3 4
dublin town1 2 2 8 10 6 7 8 9
dublin town1 3 12 13 15 11 12 13 14
dublin town2 4 1 2 3 5 1 2 3 4
dublin town2 5 6 7 8 10 6 7 8 9
dublin town2 6 11 12 13 15 1 12 13 14
http://sqlfiddle.com/#!2/0bbe7/1/0
Using INNER JOIN,
select a.*
from bigcities a inner join bigcities b
on a.city = b.city
and a.town = b.town
and a.id != b.id
and (a.code1 = b.code1
or a.code2 = b.code2
or a.code3 = b.code3
or a.code4 = b.code4
or a.area1 = b.area1
or a.area2 = b.area2
or a.area3 = b.area3
or a.area4 = b.area4
);
Demo.
This is pretty much what the exists clause can do. Here is a solution for your conditions:
select t.*
from <table> t
where exists (select 1
from <table> t2
where t2.city = t.city and
t2.town = t.town and
t2.id <> t.id and
(t2.code1 = t.code1 or t2.code2 = t.code2 or t2.code3 = t.code3 or t2.code4 = t.code4 or
t2.area1 = t.area1 or t2.area2 = t.area2 or t2.area3 = t.area3 or t2.area4 = t.area4
)
You can do it with the following query
--We do a query to the table to get the rows and then we do a subquery
--to get all the rows with the same criteria. We know it is repeated
--because the counter of rows > 1.
--If you want to get only where it is repeated 2 o 3, etc, you only need to change
--the COUNT() > 1
SELECT *
FROM tableName t
WHERE (
SELECT COUNT(*) FROM tableName tRep WHERE
t.city = tRep.city AND
t.town = tRep.town AND
((t.code1 = tRep.code1 AND t.code2 = tRep.code2 AND t.code3 = tRep.code3 AND t.code4 = tRep.code4) OR
(t.area1 = tRep.area1 AND t.area2 = tRep.area2 AND t.area3 = tRep.area3 AND t.area4 = tRep.area4))
) > 1
I am struggle with mysql query. please help me.
This is my query, i getting correct result but i need to modify the result in mysql.
SELECT bu.username,
bg.id as goal_id,
br.id as reason_id,
(SELECT COUNT(test_reason_id) FROM test_rank WHERE test_reason_id = br.id) as point
FROM
test_goal AS bg INNER JOIN test_reason AS br ON
br.user_id=bg.user_id INNER JOIN test_user AS bu ON
br.user_id=bu.id
WHERE
bg.id = br.test_goal_id
GROUP BY
bg.id
ORDER BY
point DESC
Tabble-1
My actual table look like this when i use ORDER BY point DESC then its look like Table-2
username goal_id reason_id point
khan 8 3 2
john 6 9 5
yoyo 5 21 4
smith 11 6 5
Tabble-2
My result set look like this
username goal_id reason_id point
john 6 9 5
smith 11 6 5
yoyo 5 21 4
khan 8 3 2
But i want my result set like this
username goal_id reason_id point rank
john 6 9 5 1
smith 11 6 5 2
yoyo 5 21 4 3
khan 8 3 2 4
is this possible? please can any one help me. it too difficult for me.
Add a row count variable like this:
select a.*, (#row := #row + 1) as rank
from (
SELECT bu.username,
bg.id as goal_id,
br.id as reason_id,
(SELECT COUNT(test_reason_id) FROM test_rank WHERE test_reason_id = br.id) as point
FROM
test_goal AS bg INNER JOIN test_reason AS br ON
br.user_id=bg.user_id INNER JOIN test_user AS bu ON
br.user_id=bu.id
WHERE
bg.id = br.test_goal_id
GROUP BY
bg.id
ORDER BY
point DESC
) a, (SELECT #row := 0) r
See this simplified SQLFiddle example
I've tried a few of the similar SO questions, but I can't seem to figure it out.
On the first inner join, I only want to bring in DISTINCT function columns code and serial_id. So when I do my SUM selects, it calculates one per distinct. Ie there are multiple rows with the same func.code and func.serial_id. I only want 1 of them.
SELECT
sl.imp_id,
lat.version,
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN functions func ON sl.id = func.slot_id
INNER JOIN latest_status lat ON lat.code = func.code
AND lat.serial_id = func.serial_id
WHERE sl.id=55
GROUP BY sl.imp_id, lat.version
EDIT 2 - sample data explanation -------------------
slots - id, imp_id, name
functions - id, slot_id, code, serial_id
latest_status - id, code, serial_id, version, status
**slots**
id imp_id name
1 5 'the name'
2 5 'another name'
3 5 'name!'
4 5 'name!!'
5 5 'name!!!'
6 5 'testing'
7 5 'hi'
8 5 'test'
**functions**
id slot_id code serial_id
1 1 11HRK 10
2 2 22RMJ 11
3 3 26OLL 01
4 4 22RMJ 00
6 6 11HRK 10
7 7 11HRK 10
8 8 22RMJ 00
**latest_status**
id code serial_id version status
1 11HRK 10 1 F
1 11HRK 10 2 P
3 22RMJ 11 1 P
4 22RMJ 11 2 F
5 26OLL 01 1 F
6 26OLL 01 2 P
7 22RMJ 00 1 F
8 22RMJ 00 2 F
After running the query, the result should look like this:
imp_id version powered functional
5 1 1 3
5 2 2 2
The function table gets rolled up based on the code, serial_id. 1 row per code, serial_id.
It then gets joined onto the latest_status table based on the serial_id and code, which is a one (functions) to many (latest_status) relationship, so two rows come out of this, one for each version.
How about using DISTINCT?
SELECT
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN (Select DISTINCT id1, code, serial_id from functions) f On sl.rid = f.id1
INNER JOIN latest_status lat ON lat.code = f.code
AND lat.serial_id = f.serial_id
WHERE sl.id=55
GROUP BY sl.imp_id, lat.version
If you want only the distinct code and serial_id, you need to group by those not the imp_id and version. And end up with something like
SELECT
SUM(IF(lat.status = 'P',1,0)) AS powered,
SUM(IF(lat.status = 'F',1,0)) AS functional
FROM slots sl
INNER JOIN functions func ON sl.rid = func.id1
INNER JOIN latest_status lat ON lat.code = func.code
AND lat.serial_id = func.serial_id
WHERE sl.id=55
GROUP BY func.code, func.serial_id
However, this could all be rubish, without more data as tgo what some of those other columns are, but they dont seem to be the ones you wanted to group by.