Составление таблиц Average и LEFT JOIN

Я пытаюсь объединить среднее значение столбца rating на основе postid с другой таблицей.

Я создал этот код, который вычисляет среднее значение rating, и он работает:

SELECT post_rating.postid, 
       AVG(post_rating.rating) 
FROM post_rating 
GROUP BY post_rating.postid"

Однако, когда я пытаюсь присоединиться, это не срабатывает, как показано ниже:

$join = ' LEFT JOIN ('SELECT post_rating.postid, 
                      AVG(post_rating.rating) 
                      FROM post_rating 
                      GROUP BY post_rating.postid') AS post_rating 
            ON post_rating.postid=theList.id';

Как мне присоединиться к этому коду или есть лучший способ сделать это? Спасибо!

Весь код, который я использую:

<?php

$pdo = new PDO('mysql:host=localhost;dbname=myDB', 'root', 'root');
$select = 'SELECT theList.id, theList.name, post_rating.rating, post_rating.postid';
$from = ' FROM theList';
$where = ' WHERE TRUE';
$join = ' LEFT JOIN ('SELECT post_rating.postid, AVG(post_rating.rating) FROM post_rating GROUP BY post_rating.postid') AS post_rating ON post_rating.postid=theList.id';
$opts = isset($_POST['filterOpts'])? $_POST['filterOpts'] : array('');
if (in_array("pub", $opts)){
$where .= " AND pub = 1";
}
if (in_array("bar", $opts)){
$where .= " AND bar = 1";
}
if (in_array("restaurant", $opts)){
$where .= " AND restaurant = 1";
}
if (in_array("club", $opts)){
$where .= " AND club = 1";
}

$sql = $select . $from . $join . $where;
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);
?>

Вот упрощенные версии моих таблиц:

таблица postid

id | postid | rating
--------------------
1  |    3   |    5
2  |    3   |    4
3  |    1   |    3

Таблица списка

id | name 
----------
1  | name1   
2  | name2   
3  | name3

По сути, я пытаюсь вывести:

id | name  | rating
------------------
1  | name1 |   3
2  | name2 |   0
3  | name3 |   4.5

«это не работает» - Что такое сообщение об ошибке MySQL?

HoldOffHunger 03.10.2018 19:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
1
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Теперь я вижу проблему, о которой вы пытались рассказать мне в своих предыдущих комментариях к вопросу, вы по какой-то причине закончили строку $join, поэтому большая часть запроса не будет включена

Итак, эта строка

$join = ' LEFT JOIN ('SELECT post_rating.postid, AVG(post_rating.rating) 
            FROM post_rating GROUP BY post_rating.postid') AS post_rating 
            ON post_rating.postid=theList.id';

(см. цвет кода показывает ошибку)

Так что поправьте

$join = ' LEFT JOIN (SELECT post_rating.postid, AVG(post_rating.rating) 
            FROM post_rating GROUP BY post_rating.postid) AS post_rating 
            ON post_rating.postid=theList.id';

Могу ли я предложить вам добавить в PDO обработку EXCEPTION, чтобы в браузере сообщали вам об ошибках. Сделайте это в своем коде подключения

$pdo = new PDO(.......);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

По-прежнему появляется ошибка 500! Что-то еще мне не хватает? В очередной раз благодарим за помощь!

tbowden 03.10.2018 19:52

500 ошибок обычно довольно серьезны. Просматривали ли вы журнал ошибок PHP, чтобы узнать, есть ли какие-либо сообщения, которые помогут определить проблему?

RiggsFolly 03.10.2018 19:54

«По-прежнему появляется ошибка 500! Что-то еще мне не хватает?» Перейдите к другому хостинг-провайдеру, который не навязывает вам белый экран смерти при выходе из строя парсера PHP. @tbowden .. тогда у вас будет более полезная ошибка. Или сделайте то, что говорит RiggsFolly, просматривает файл ошибок PHP, если у вас есть к нему доступ ... если у вас нет доступа к нему, используйте это в своем коде ini_set('error_log', 'your/path/to/errors.log');

Raymond Nijland 03.10.2018 19:54

Я предполагаю, что вы изменили что-то еще, кроме этого! Эта ошибка должна была вызвать довольно обычную ошибку, а не 500.

RiggsFolly 03.10.2018 19:55

Здесь можно многому научиться! Спасибо ребята. Я выяснил ошибку! Почему-то сказано: «1054 Неизвестный столбец post_rating.rating» в «списке полей».

tbowden 03.10.2018 20:18

Столбец рейтинга в таблице post_rating определенно существует!

tbowden 03.10.2018 20:21

Вам нужен псевдоним: AVG(post_rating.rating) AS rating.

Barmar 03.10.2018 22:31

Кстати, вам не нужно говорить post_rating. перед всеми столбцами в подзапросе, поскольку там только одна таблица.

Barmar 03.10.2018 22:31
Ответ принят как подходящий

Я думаю, что вы подходите к этому запросу излишне сложным образом. Просто выполните Left Join между таблицами, рассмотрите theList как крайнюю левую таблицу и вычислите Avg() в группе по на postid:

SELECT tl.id, 
       tl.name, 
       AVG(pr.rating) AS rating 
FROM post_rating AS pr 
LEFT JOIN theList AS tl ON tl.id = pr.postid 
GROUP BY tl.id, tl.name  

Ваш PHP-код будет выглядеть следующим образом:

<?php 
$pdo = new PDO('mysql:host=localhost;dbname=myDB', 'root', 'root');
$select = 'SELECT tl.id, 
                  tl.name, 
                  AVG(pr.rating) AS rating ';

$from = ' FROM post_rating AS pr ';
$where = ' WHERE 1 = 1 ';
$join = ' LEFT JOIN theList AS tl ON tl.id = pr.postid ';
$opts = isset($_POST['filterOpts'])? $_POST['filterOpts'] : array('');
if (in_array("pub", $opts)){
    $where .= " AND pub = 1";
}
if (in_array("bar", $opts)){
    $where .= " AND bar = 1";
}
if (in_array("restaurant", $opts)){
    $where .= " AND restaurant = 1";
}
if (in_array("club", $opts)){
    $where .= " AND club = 1";
}

$group = ' GROUP BY tl.id, tl.name ';

$sql = $select . $from . $join . $where . $group;
$statement = $pdo->prepare($sql);
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_ASSOC);
$json = json_encode($results);
echo($json);
?>

Действительно? В этом запросе неправильно используется расширенная функция MySQL GROUP BY. Другими словами, используются столбцы в SELECT без использования их в GROUP BY. Это не жалоба ANSI SQL и может привести к несвязанным данным для каждого неагрегированного столбца выбора, который не является в группе по.

Raymond Nijland 03.10.2018 19:59

@RaymondNijland хотя и исправлен, но tl.id и pr.postid были функционально зависимы через соединение

Madhur Bhaiya 03.10.2018 20:01

Особые случаи функциональной зависимости могут работать только тогда, когда столбец, используемый в GROUP BY, имеет (PRIMARY или UNIQUE) ключевую зависимость dev.mysql.com/doc/refman/5.7/en/…, по крайней мере, это то, что я понял при чтении документации.

Raymond Nijland 03.10.2018 20:05

@RaymondNijland, спасибо за разъяснения. Хотя я чувствовал, что можно с уверенностью предположить, что tl.id является первичным ключом в таблице theList, и поскольку мы присоединяемся, используя tl.id = pr.postid; не имеет значения, группирую я по tl.id или pr.postid

Madhur Bhaiya 03.10.2018 20:08

«не имеет значения, группирую я по tl.id или pr.postid». В документе объясняется, что столбец или столбцы, используемые в GROUP BY, используются для функциональной зависимости ... «Таким образом, co.name - функционально зависит от столбцов GROUP BY, и запрос действителен.», так что ясно, что это похоже, это имеет значение ... Кроме того, функциональные зависимости, производные от ключей с несколькими столбцами (JOINING) и от Equalities, следует за этим, если вы присмотритесь.

Raymond Nijland 03.10.2018 20:11

@MadhurBhaiya Я успешно использовал этот код для получения рейтинга. Благодарю вас! Однако теперь оператор WHERE TRUE не работает и не получает ошибку! Вы знаете, как я могу это решить?

tbowden 03.10.2018 21:26

@tbowden зачем тебе Где правда?

Madhur Bhaiya 03.10.2018 21:27

У меня есть несколько флажков, которые в основном помогают мне уточнить запрос. Таким образом, код работает, проверяя, установлены ли флажки, а затем возвращает результаты, в зависимости от того, какие флажки установлены! - Вы видите, как это работает наверху? Спасибо!

tbowden 03.10.2018 21:34

@tbowden проверьте обновленный ответ. Я также добавил модифицированный PHP-код

Madhur Bhaiya 03.10.2018 21:47

Идеально! Огромное спасибо.

tbowden 03.10.2018 21:54

Другие вопросы по теме