MySQL множественный SELECT используется с WHERE - PullRequest
1 голос
/ 19 апреля 2020

В настоящее время я работаю над таблицами данных и пытаюсь создать небольшой обзор с p ie -картами и прочим. Для этого мне нужно умножить разные столбцы и получить их сумму (например, SUM(episodes*length) AS full_length_sum).

Проблема в том, что мне также нужна сумма некоторых определенных c записей. Итак, я придумал оператор WHERE. К сожалению, это используется для всей таблицы. Поэтому я перешел на Google и нашел UNION, чтобы получить несколько «разных» SELECT. К сожалению, я делаю что-то не так и не знаю, что именно.

Я просто делаю это как маленькое хобби, и мои навыки в MySQL и PHP очень низкие. Больше всего я «учусь» методом проб и ошибок. Поэтому я надеюсь, что кто-то может указать мне правильное направление.

Вот мой текущий код без множественного выбора:

$conn = new mysqli($dbservername, $dbuser, $dbpass, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error . "<br>");
}

$sql = "
    SELECT id, id_mal, title, genre, studio, release_date, lastwatched_date, cover, type, progress, episodes, watch_counter, status, comment, rating, favorite,
    (episodes*length) AS full_length, (watch_counter*episodes*length) AS current_length,
    SUM(episodes*length) AS full_length_sum, SUM(watch_counter*episodes*length) AS current_length_sum
    FROM dt_series";

        $result = mysqli_query($conn, $sql);
        $row  = mysqli_fetch_assoc($result);

        $sum_fl = bcdiv($row['full_length_sum'] / 60, 1, 2);
        $sum_cl = bcdiv($row['current_length_sum'] / 60, 1, 2);

        $conn->close();

и начиная с $sql = " моя попытка получить несколько вариантов выбора:

$sql = "
    SELECT id, id_mal, title, genre, studio, release_date, lastwatched_date, cover, type, progress, episodes, watch_counter, status, comment, rating, favorite,
    (episodes*length) AS full_length, (progress*length) AS progress_length, (watch_counter*episodes*length) AS current_length,
    SUM(episodes*length) AS full_length_sum, SUM(watch_counter*episodes*length) AS current_length_sum
    FROM dt_series 
    UNION 
    SELECT progress, length, 
    SUM(progress*length) AS progress_length_sum 
    FROM dt_series 
    WHERE status = 0";

        $result = mysqli_query($conn, $sql);

Я также пробовал только с SUM( во втором, например:

  UNION 
    SELECT 
    SUM(progress*length) AS progress_length_sum 
    FROM dt_series 

Так что ... это не работает для меня, и мне интересно, почему.

PS: я знаю, что это, вероятно, не безопасный способ обработки sql (кто-то сказал мне), но я использую это только в моем защищенном веб-пространстве .htaccess, и там не хранятся важные данные.

edit:

Прежде всего: спасибо всем, кто пытается мне помочь. Я постараюсь дать вам дополнительную информацию о том, что я хочу попробовать.

Итак, в целом у меня есть таблица 'dt_series', в которой я храню всю необходимую информацию о сериале, который я планировал посмотреть или уже полностью просмотрел ,

Для этого у меня также есть столбец для длины эпизода, который я называю length, и для количества эпизодов, называемых episodes, а также счетчик (если я смотрел серию полностью с во всех эпизодах счетчик поднимается на один) называется watch_counter.

Я построил простой график P ie, используя эту информацию, которую я отметил выше. Что я получил, так это то, что эта диаграмма P ie в настоящее время отображает общую продолжительность (время просмотра) всех сохраненных мной серий (количество эпизодов * длина эпизода / SUM(episodes*length) AS full_length_sum). После этого я добавляю общее время, потраченное на просмотр (счетчик часов * эпизодов * длина / SUM(watch_counter*episodes*length) AS current_length_sum).

Теперь я хочу добавить значение длины уже просмотренных эпизодов серии, которая еще не завершена , В настоящее время я посмотрел 16 эпизодов серии, в которой 37 эпизодов. Поэтому я не могу взять SUM(watch_counter*episodes*length) AS current_length_sum, потому что watch_counter по-прежнему равен 0. И даже если бы это было 1, я бы получил общую длину всей серии, но посмотрел только 16 эпизодов.

Но у меня есть столбец в таблице, которая называется status, и у меня также есть столбец с именем progress для количества эпизодов, которые я просмотрел. Итак, моя идея состоит в том, что я хочу получить SUM(progress*length) AS progress_length_sum Итак, я получаю сумму текущих просмотренных эпизодов * длительности эпизодов, где статус равен «0» (просмотр).

Ответы [ 2 ]

2 голосов
/ 19 апреля 2020

Самая очевидная вещь неправильная с SQL, даже до того, как мы перейдем к UNION, - это агрегированные выражения (SUM) в списке SELECT вместе со столбцами (неагрегированными выражениями), которых нет в GROUP BY

Все строки, которые соответствуют условию в предложении WHERE, свернуты в одну строку, а значения первых восемнадцати выражений не определены , они будут получены из некоторых строка в группе, но нет гарантии, из какой строки они будут возвращены.

(Мы ожидаем, что в условии «status = 0» более одной строки, которая соответствует первому запросу, это не имеет значения, совпадают ли ноль, одна или несколько строк, запрос вернет ровно одну строку или ...

При другой настройке sql_mode, включая ONLY_FULL_GROUP_BY, мы получили бы возвращаемую ошибку И это поведение более согласуется с большинством других СУБД (SQL Сервер, Oracle, Teradata и др.)

На самом деле невозможно дать совет по добавлению UNION или UNION ALL к существующему запросу, когда он выглядит так, будто запрос не работает.

Как правило, когда мы получаем агрегаты, мы получаем одну строку для всего набора ...

SELECT SUM( t.length * t.episodes )  AS full_length 
  FROM dt_series t
 WHERE t.status = 0

Или мы получаем агрегаты для некоторых подмножеств строк, объединяя строки в группы

Например, по значению studio

SELECT t.studio
     , SUM( t.length * t.episodes )  AS full_length 
  FROM dt_series t
 WHERE t.status = 0
 GROUP
    BY t.studio
 ORDER
    BY t.studio 

Без спецификация, лучше переданная примерами данных и ожидаемым результатом, на самом деле невозможно дать совет о добавлении UNION.

Мы можем заметить, что операторам UNION и UNION ALL требуется, чтобы два набора содержали одинаковое количество столбцов, и те же (или совместимые) типы данных

В качестве примера:

 SELECT 1 AS col_one, 'two' AS col_two, buckle*myshoe AS col_3
   FROM ...
  WHERE ...
  UNION ALL 
 SELECT 5 , 'six', pickup_sticks 
   FROM ...
  WHERE ...

Но опять же, я не могу рекомендовать добавлять оператор набора UNION, не понимая, что именно мы пытаемся достичь.

1 голос
/ 19 апреля 2020

UNION не работает с разным количеством столбцов. Взгляните на этот пост, который также может вам помочь: mysql -union-Different-Number-of-Columns

...