Average and comparative left join MySQL - php

I'm trying to fetch information from 2 different MySQL tables.
The primary table is this one:
From this one I use the information to get the average rate from this:
How can I write an SQL query that will get me the average rating by counting all the rows with rating_house = house_id, and sort it by highest rating and if equal ratings, the one with the most rates.
This is what I have come up with myself:
$sql = "SELECT l.location_address, "
. "r.rating_structure+r.rating_inventory+r.rating_service/3 AS average "
. "FROM houses h "
. "LEFT JOIN rating r ON h.house_id = r.rating_house "
. "LEFT JOIN location l ON h.house_address = l.location_id "
. "WHERE h.house_deleted IS NULL SORT BY average DESC LIMIT 10";
$result = $db_connect->prepare($sql);
if($result->execute()){
while($user_data = $result->fetch(PDO::FETCH_ASSOC)){
$user_data['location_address']."<br>";
}
}
However I get no output?

For performance use INNER JOINs instead of LEFT JOINs if you know that the related rows must exist.
SELECT l.location_address,
(SUM(r.rating_structure)+SUM(r.rating_inventory)+SUM(r.rating_service))/3 AS average
FROM houses h
INNER JOIN rating r ON h.house_id = r.rating_house
INNER JOIN location l ON h.house_address = l.location_id
WHERE h.house_deleted IS NULL
GROUP BY l.location_address
ORDER BY 2,
(SUM(r.rating_structure)+SUM(r.rating_inventory)+SUM(r.rating_service)) DESC
LIMIT 10

Below query should return houses sorted by average ratings:
select h.house_id, (sum(hr.rating_structure) + sum(rating_inventory) + sum(rating_service))/3 as "average"
from house h left outer join house_rating hr on h.house_id = hr.rating_house
group by h.house_id
order by average

Related

Filter Data By month Mysql

$listSQL = "SELECT op.name as prodname,count(*) total
FROM oc_order_product op
INNER JOIN oc_order o ON op.order_id = o.order_id
INNER JOIN oc_product_to_category p2c ON op.product_id = p2c.product_id
INNER JOIN oc_category_description cd ON cd.category_id = p2c.category_id ";
$listSQL = $listSQL."where lower(cd.name) LIKE '%".$category_name."%'
AND YEAR(o.date_added) = '".$StartDate."'
AND o.order_status_id > '0' ";
$listSQL = $listSQL."GROUP BY op.name ORDER BY o.date_added ASC";
I have this query where i am displaying product names and count by year.
I want to display Product name, and for each product, show month and count for that month for that particular year.
for example for year 2015, show all 12 months and under which show count of products for that month.
Thanks
Your original query looks pretty close, but using non-grouped, non-aggregated fields "outside" a group by is usually not a good idea unless they came from a table whose full primary key was part of the group by list. That said, this should give you what you want.
SELECT op.name AS prodname
, YEAR(o.date_added) AS oYear
, MONTH(o.date_added) AS oMonth
, COUNT(DISTINCT o.order_id) AS numOfOrders
FROM ...
GROUP BY prodname, oYear, oMonth
ORDER BY prodname, oYear, oMonth
;
[...] being your original FROM and WHERE

Trying to join 3 mysql tables but I do not get the expected result. What is mistake?

The below mysql query
SELECT *
FROM alerts_list l, alerts_data d, alerts_push_data p
WHERE p.push_data_hash = d.alerts_data_hash
AND p.push_data_alert_id = l.alerts_id
AND d.alerts_data_id = l.alerts_id
AND d.alerts_data_hash = 'JiaYRSVNZxgE'
shows the results of JiaYRSVNZxgE by joining three tables.
Here are the tables that I use and the columns that I want to connect between them:
table alerts_list
column: alerts_id
table alerts_push_data
column: push_data_alert_id
column: push_data_hash
table alerts_data
column: alerts_data_id
column: alerts_data_hash
What I want to achieve is:
connect push_data_alert_id with alerts_id
connect alerts_data_id with alerts_id
but show only the results where alerts_data_hash and push_data_hash is "abcdef"
Unfortunately my query results to no results found, but there are results in reality.
What I am doing wrong?
You could use MySQL JOINS to perform that operation quite easily like so:
<?php
// USING NORMAL JOIN:
// WE NOW ADD AN EXTRA LAYER (THE VARIABLE $fldVal)
// IN THE CASE THAT YOUR VALUE ('JiaYRSVNZxgE') IS DYNAMIC...
$fldVal = 'JiaYRSVNZxgE';
$sql = "SELECT DISTINCT *
FROM alerts_list l
JOIN alerts_data d ON d.alerts_data_id=l.alerts_id
JOIN alerts_push_data p ON p.push_data_alert_id=l.alerts_id
WHERE d.alerts_data_hash='" . $fldVal . "'";
// USING LEFT JOIN:
// WE NOW ADD AN EXTRA LAYER (THE VARIABLE $fldVal)
// IN THE CASE THAT YOUR VALUE ('JiaYRSVNZxgE') IS DYNAMIC...
$fldVal = 'JiaYRSVNZxgE';
$sql = "SELECT DISTINCT *
FROM alerts_list l
LEFT JOIN alerts_data d ON d.alerts_data_id=l.alerts_id
LEFT JOIN alerts_push_data p ON p.push_data_alert_id=l.alerts_id
WHERE d.alerts_data_hash='" . $fldVal . "'";
// USING INNER JOIN:
// WE NOW ADD AN EXTRA LAYER (THE VARIABLE $fldVal)
// IN THE CASE THAT YOUR VALUE ('JiaYRSVNZxgE') IS DYNAMIC...
$fldVal = 'JiaYRSVNZxgE';
$sql = "SELECT DISTINCT *
FROM alerts_list l
INNER JOIN alerts_data d ON d.alerts_data_id=l.alerts_id
INNER JOIN alerts_push_data p ON p.push_data_alert_id=l.alerts_id
WHERE d.alerts_data_hash='" . $fldVal . "'";
::AND YET A NEW UPDATE WITH GROUP BY CLAUSE::
<?php
// WE NOW ADD AN EXTRA LAYER (THE VARIABLE $fldVal)
// IN THE CASE THAT YOUR VALUE ('JiaYRSVNZxgE') IS DYNAMIC...
$fldVal = 'JiaYRSVNZxgE';
$sql2 = "SELECT DISTINCT *
FROM alerts_list AS A_LIST
LEFT JOIN alerts_push_data A_PUSH ON A_PUSH.push_data_alert_id=A_LIST.alerts_id
LEFT JOIN alerts_data A_DATA ON A_DATA.alerts_data_hash=A_PUSH.push_data_hash
WHERE A_DATA.alerts_data_hash='" . $fldVal . "'
GROUP BY A_LIST.alerts_id";
TEST-CASE QUERY
SELECT DISTINCT *
FROM alerts_list AS A_LIST
LEFT JOIN alerts_push_data A_PUSH ON A_PUSH.push_data_alert_id=A_LIST.alerts_id
LEFT JOIN alerts_data A_DATA ON A_DATA.alerts_data_hash=A_PUSH.push_data_hash
WHERE A_DATA.alerts_data_hash='iSg2loGJDaWs'
GROUP BY A_LIST.alerts_id
RESULT
And these are to be expected because I simulated only 2 Rows in all the other Tables except the alerts_list which has 10 Rows.
Result of dumping the Query Above
Table: alerts_list
Table: alerts_data
Table: alerts_push_data

Getting SUM based on quantity in MySQL?

I have this tables
ORDERS
orders_id
order_article_id
order_invoice_id
order_customer_id
order_qty
ARTICLES
articles_id
article_name
article_qty
article_price
article_amount
CUSTOMERS
customers_id
customer_name
customer_position
customer_office
And SQL Join Table
$sql="SELECT customer_name, article_name, orders_id FROM orders
LEFT JOIN articles ON order_article_id = articles_id
LEFT JOIN customers on order_customer_id = customers_id";
From this query I need to get AMOUNT.
Amount is example
USER: MICHAEL
AMOUNT: ORDER ID = order_article_id + order_qty;
Is it possible to do that in MySQL or i need some addition PHP code?
You can do it in MySQL, using a GROUP BY query and a SUM() aggregate function:
SELECT
c.customer_name,
SUM(a.article_price*a.article_quantity) AS amount
FROM
orders o LEFT JOIN articles a
ON o.order_article_id = a.articles_id
LEFT JOIN customers c
ON o.order_customer_id = c.customers_id
GROUP BY
c.customers_id,
c.customer_name
you might want to obtain the AMOUNT per order, then you need to group by also for the order_id:
GROUP BY
o.orders_id,
c.customers_id,
c.customer_name

MySQL JOIN and MAX

Hi I've got a query which does what I want to by displaying reviews which are rated first then followed by reviews which have yet to be rated. However I can't seem to get it to order correctly.
What the result should look like:
5
4
0
0
...
At the moment it is doing this:
4
5
0
0
...
Here is my query
$sql = $db->query( "
SELECT branch.*, MAX(review.rating) AS m
FROM branch
LEFT OUTER JOIN review ON branch.bid = review.bid
WHERE branch.address2 LIKE '$query' OR branch.postcode LIKE '$query-%'
GROUP BY branch.bid
ORDER BY m DESC, branch.branch ASC
LIMIT $start,$limit
" ) or die( "Select failed: (" . $db->errno . ") " . $db->error );
Sub-query solution by Meghraj Choudhary should work.
However, Joins are faster. Sub-queries require additional disk accessing. Assuming branch.bid is a primary key the following should be faster:
SELECT b1.*, b2.m FROM branch b1
INNER JOIN
(
SELECT branch.bid, MAX(review.rating) AS m
FROM branch
LEFT OUTER JOIN review ON branch.bid = review.bid
WHERE branch.address2 LIKE '$query' OR branch.postcode LIKE '$query-%'
GROUP BY branch.bid
LIMIT $start,$limit
) b2 ON
b1.bid = b2.bid
ORDER BY b2.m DESC, b1.branch ASC
I have not tried this. So, please try it and post back.

How to get results count from each entry ID - PHP/SQL?

here is a small sample of what im trying.. as its hardly to code it here I have uploaded an image..
http://i46.tinypic.com/5bxn5u.png
just want to display the total number of reservations for each room.. thanks
You'll want to join the tables together and use COUNT() with a GROUP BY:
SELECT
a.id, a.name, COUNT(*) AS num_reservations
FROM
availables a
LEFT JOIN reservations r
ON r.available_id = a.id
GROUP BY
a.id
This should give you a list of each room with a total number of reservations each has.
To put it into your existing query, you can use the following:
$coordinator = (isset($_GET['uidse']) && is_numeric($_GET['uidse'])) ? (int)$_GET['uidse'] : 0;
$result = mysql_query("SELECT *, COUNT(*) AS num_reservations FROM availables LEFT JOIN reservations ON availables.id=reservations.available_id WHERE coordinator='" . $coordinator . "' GROUP BY availables.id");
I placed $coordinator outside of the MySQL query and added very basic validation/sanitization to save you from a SQL-Injection headache in the future.
SELECT availables.name, COUNT(*) FROM availables
LEFT JOIN reservations ON reservations.available_id = availables.id
GROUP BY reservations.available_id

Categories