As I am not good with MySQL query's so I wish someone help me for creating this kind of sql query.
I having two MySQL tables which is describe bellow:
Table Name: rating
-------------------
property_id user_id area_rate_count safety_rate_count friendly_rate_count walkability_rate_count
4 28 1 1 1 2
5 38 2 3 4 1
5 40 2 2 3 1
6 40 2 3 1 4
10 43 2 2 3 1
Table Name: listing
-------------------
property_id title
4 Sample 1
5 Sample 2
6 Sample 3
10 Sample 4
11 Sample 5
12 Sample 6
Now first I want to sum each column and divide. (area_rate_count, safety_rate_count, friendly_rate_count, walkability_rate_count). For example In property_id:5 having two times so first calculate column sum and divide by 2.
After calculation we will get this output:
Table Name: rating (After Calculation)
--------------------------------------
property_id rate
4 5
5 9 (Divided by 2 because this property_id is two times in table)
6 10
10 8
And Finally I want join this result to my listing table and result looks something like this:
Table Name: listing
-------------------
property_id title rate
4 Sample 1 5
5 Sample 2 9 (Divided by 2 becouse property_id is two times in table)
6 Sample 3 10
10 Sample 4 8
11 Sample 5 0
12 Sample 6 0
Thanks.
I think you want the avg() aggregation function along with a join:
select l.property_id, l.title,
coalesce(avg(area_rate_count + safety_rate_count + friendly_rate_count + walkability_rate_count
), 0) as rate
from listing l left outer join
property_id p
on l.property_id = p.property_id
group by l.property_id, l.title ;
If I understood it right I think you need this:
select l.property_id, l.title, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
See it here on fiddle: http://sqlfiddle.com/#!2/589d6/5
Edit
As OP asked on the comments that he wants all columns from listing here is what he want:
select l.*, coalesce(r.ssum/if(r.ct=0,1,r.ct), 0) as rate
from listing l LEFT JOIN
(select property_id,
sum(area_rate_count+safety_rate_count
+friendly_rate_count+walkability_rate_count) ssum,
count(*) ct
from rating
group by property_id ) r
ON l.property_id = r.property_id
order by l.property_id
CREATE TEMPORARY TABLE IF NOT EXISTS
temp_table ( INDEX(col_2) )
ENGINE=MyISAM
AS (
SELECT
property_id,
AVG(area_rate_count) as area_rate_count,
AVG(safety_rate_count) as safety_rate_count,
AVG(friendly_rate_count) as friendly_rate_count,
AVG(walkability_rate_count) as walkability_rate_count
FROM rating
GROUP BY property_id
)
SELECT * FROM listing L
JOIN temp_table T
ON L.property_id = T.property_id
Use the below statement to get distinct property_id with its own rate
select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id
you can then join with the other table to get the final result as below
select * from ( select property_id, sum(separaterating)/count(property_id) from (
select property_id,sum(area_rate_count , safety_rate_count , friendly_rate_count , walkability_rate_count) as separaterating from rating group by property_id AS temp ) group by
property_id) AS A inner join listing AS B on A.property_id = B.property_id
try this:
select a.prop_id as property_id, l.title, a.allratings / b.numberofreviews as rate
from
(
select property_id as prop_id, SUM(coalesce(area_rate_count,0) + coalesce(safety_rate_count,0) + coalesce(friendly_rate_count,0) + coalesce(walkability_rate_count,0)) as allratings
from rating
group by property_id
) a inner join
(
select property_id, count(distinct user_id) as numberofreviews
from rating
group by property_id
) b on a.property_id = b.property_id
inner join listing l on a.property_id = l.property_id
Try This Query
select ls.property_id,ls.title,inr.rate from listing as ls
left join
(select r.property_id as pid,r.rate/r.cnt as rate from
(select property_id,user_id,(area_rate_count+safefty_rate_count+friendly_rate_count+walkability_rate_count) as rate,count(*) as cnt from rating group by property_id) as r) as inr on inr.pid=ls.property_id
Related
I have query that make a list of payments (payment table) and I would like to have it sorted by the date of the tasks (2 separate tables - quotedb and packaging) these payments are related to
My Query:
SELECT a.*
FROM payments AS a
LEFT JOIN quotedb AS b ON a.orderid = b.id
LEFT JOIN packaging AS p ON a.orderid = p.id
WHERE a.status='Pending' AND (b.moveday<'$today' OR p.datestamp<'$today')
ORDER BY b.moveday, p.datestamp
payments table example:
id payment orderid
-------------------
1 payment1 1
2 payment2 2
3 payment3 3
4 payment4 4
5 payment5 5
6 payment6 6
quotedb table example:
id moveday
-----------
1 05.07.18 > related to payments table id 1
2 08.07.18
3 10.07.18
packaging table example:
id datestamp
-----------
4 06.07.18 > related to payments table id 4
5 07.07.18
6 19.07.18
I join results from the tables, but I have a problem with sorting, query seem to print the "packaging" table results unsorted, and then results from "quotedb" sorted by moveday
I want these results to be sorted by (joined moveday and datestamp)
You can use UNION ALL to combine quotedb and packaging tables. and use grp make a number to make Order by sequence number
SELECT a.*
FROM payments a
LEFT JOIN
(
SELECT 1 grp,id,moveday AS day
FROM quotedb
UNION ALL
SELECT 2,id,datestamp
FROM packaging
) t on a.orderid = t.id
ORDER BY t.grp,t.day
sqlfiddle
SELECT a.*
FROM payments AS a
LEFT JOIN
(
SELECT orderno, moveday AS sortdate FROM quotedb
UNION ALL
SELECT orderno, datestamp AS sortdate FROM packaging
) t on a.orderno = t.orderno
WHERE a.status='Pending' AND sortdate<'$today'
ORDER BY sortdate
I have 2 tables with information: ID, persona_id, total_amount
The persona ID can repeat dozen of times. So i get all the one persons id total_amount with query:
select d.id as debt_id, p.name as persona, sum(d.total_amount) as total_amount
from debt d
join persons p on d.persona_id = p.id group by p.name
I want to get data from each table in one query and do aritmethic propertys with the total_amount column and return it as 1 tabel.
TABLE 1
id persons_id total_amount
1 2 50
2 3 100
3 2 200
4 5 300
5 1 500
TABLE 2
id persons_id total_amount
1 2 25
2 1 100
3 5 50
4 3 100
5 4 300
As a result i want to get the 2 tables comined with arithmetic operation (-, +, / , * ) of Total amount columns.Basicaly a change to get the ending result total amount in form i want for different cases.
What worked for me based on JohnHC answear was :
select c.id, c.persona_id, c.total_amount - d.total_amount as new_total
from ( select c.id , c.persona_id, sum(c.total_amount) as total_amount from credit c
join persons p on c.persona_id = p.id
group by p.name) c
inner join ( select d.id, d.persona_id, sum(d.total_amount) as total_amount from debt d
join persons p on d.persona_id = p.id
group by p.name) d
on c.persona_id = d.persona_id
group by c.id, c.persona_id
If you want the total, try:
select id, person_id, sum(total_amount)
from
(
select id, person_id, total_amount
from table1
union all
select id, person_id, total_amount
from table2
)
group by id, person_id
If you want to do other things, try:
select t1.id, t1.person_id, t1.total_amount [+ - / *] t2.total_amount as new_total
from table1 t1
inner join table2 t2
on t1.id = t2.person_id
group by t1.id, t1.person_id
I have the following tables, for example:
invoices
ID Name
1 A
2 B
3 C
4 D
5 E
transactions
ID Invoice_ID User_ID
1 1 10
2 1 10
3 1 10
4 2 30
5 3 20
6 3 40
7 2 30
8 2 30
9 4 40
10 3 50
Now I want to make a select that will pull the invoices and the user_id from the related transactions, but of course if I do that I won't get all the ids, since they may be distinct but there will be only one column for that. What I want to do is that if there are distinct User_ids, I will display a pre-defined text in the column instead of the actual result.
select invoices.id, invoices.name, transactions.user_id(if there are distinct user_ids -> return null)
from invoices
left join transactions on invoices.id = transactions.invoice_id
and then this would be the result
ID Name User_ID
1 A 10
2 B 30
3 C null
4 D 40
5 E null
Is this possible?
You can do the following :
select
invoices.id,
invoices.name,
IF (
(SELECT COUNT(DISTINCT user_id) FROM transactions WHERE transactions.invoice_id = invoices.id) = 1,
(SELECT MAX(user_id) FROM transactions WHERE transactions.invoice_id = invoices.id),
null
) AS user_id
from invoices
Or, alternatively, you can use the GROUP_CONCAT function to output a comma-separated list of users for each invoice. It is not exactly what you asked, but maybe in fact it will be more useful :
select
invoices.id,
invoices.name,
GROUP_CONCAT(DISTINCT transactions.user_id SEPARATOR ',') AS user_ids
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
Try somethingh like:
select i.id, i.name, t.user_id
from invoices i left join
(
select invoice_ID, User_ID
from transactions
group by invoice_ID
having count(invoice_ID)=1
) t on i.id=t.invoice_id
SQL fiddle
You could list all the transactions that have multiple user ids, like this:
select invoices.id, invoices.name, null
from invoices
left join transactions on invoices.id = transactions.invoice_id having count(distinct transactions.user_id) > 1
Also, I think this CASE might suit your needs here:
select invoices.id, invoices.name,
case when count(distinct transactions.user_id) > 1 then null else transactions.user_id end
from invoices
left join transactions on invoices.id = transactions.invoice_id
group by invoices.id
although, I'm not sure this is syntactically correct
Hi I have a table called orders_pending
it has columns order_number and model
order_number | model
1 1
1 2
2 1
2 3
2 5
3 5
4 2
As you can see 1 order can have multiple models , in my table no unique key , but if i take both the order number and model it is unique .
I want a result like this
order_number | model
2 1
2 3
2 5
1 1
1 2
Only order_number's that have more than one model and it should be sort according to the number of orders which are presented in the table
I tried lots of solutions but could not succeed .
Please help . Thanks in advance .
Create a subquery which gets the total number of models and filters out order_number which has multiple models. The result is then join with the table itself. Use the TotalCount column to order the result.
SELECT a.*
FROM orders_pending a
INNER JOIN
(
SELECT order_number, COUNT(*) TotalCount
FROM orders_pending
GROUP BY order_number
HAVING COUNT(*) > 1
) b ON a.order_number = b.order_number
ORDER BY b.TotalCount DESC, a.order_number, a.model
SQLFiddle Demo
First we get the order_numbers which have more than one model.
SELECT order_number, COUNT(*) AS how_many_orders
FROM
orders_pending
GROUP BY order_number
HAVING COUNT(*) > 1;
Then we join this to get every row in the table that belong to those order_numbers.
SELECT
op.order_number, op.model
FROM
orders_pending op
INNER JOIN (
SELECT order_number, COUNT(*) AS how_many_orders
FROM
orders_pending
GROUP BY order_number
HAVING COUNT(*) > 1
) sq ON op.order_number = sq.order_number
ORDER BY how_many_orders, op.order_number
I've got a budget table:
user_id product_id budget created
-----------------------------------------------------------------
1 1 300 2011-12-01
2 1 400 2011-12-01
1 1 500 2011-12-03
2 2 400 2011-12-04
I've also got a manager_user table, joining a manager with the user
user_id manager_id product_id
------------------------------------
1 5 1
1 9 2
2 5 1
2 5 2
3 5 1
What I'd like to do is grab each of the user that's assigned to Manager #5, and also get their 'budgets'... but only the most recent one.
Right now my statement looks like this:
SELECT * FROM manager_user mu
LEFT JOIN budget b
ON b.user_id = mu.user_id AND b.product_id = mu.product_id
WHERE mu.manager_id = 5
GROUP BY mu.user_id, mu.product_id
ORDER BY b.created DESC;
The problem is it doesn't pull the most recent budget. Any suggestions? Thanks!
To accomplish your task you can do as follows:
select b1.user_id,
b1.budget
from budget b1 inner join (
select b.user_id,
b.product_id,
max(created) lastdate
from budget b
group by b.user_id, b.product_id ) q
on b1.user_id=q.user_id and
b1.product_id=q.product_id and
b1.created=q.lastdate
where b1.user_id in
(select user_id from manager_user where manager_id = 5);
I'm assuming here that your (user_id, product_id, created) combination is unique.
For what it's worth, here's the code that returned what I was looking for:
SELECT DISTINCT(b1.id),mu.user_id,mu.product_id,b1.budget,b1.created
FROM budget b1
INNER JOIN (
SELECT b.user_id, b.product_id, MAX(created) lastdate
FROM budget b
GROUP BY b.user_id, b.product_id) q
ON b1.user_id=q.user_id AND
b1.product_id=q.product_id AND
b1.created=q.lastdate
RIGHT JOIN manager_user mu
ON mu.user_id = b1.user_id AND
mu.product_id = b1.product_id
WHERE mu.manager_id = 5;
Thanks for the help Andrea!