Не удается получить определенные поля в MySQL с группированием по запросу - PullRequest
0 голосов
/ 02 марта 2019

У меня есть следующий запрос (и я пробовал много вариантов):

select housedata.housecode, housedata.name, min((pergroup + (perguest *  GREATEST((2 - guests_included),0)))) as mincalculated 
from housedata
inner join availabilitydata 
where housedata.housecode = availabilitydata.housecode 
and  datediff(departure, arrival) = 7 group by housedata.housecode

Это отлично работает, но мне нужно больше полей из таблицы доступности данных.Как только я пытаюсь добавить эти жалобы MySQL:

[42000] [1055] Выражение № 4 списка SELECT отсутствует в предложении GROUP BY и содержит неагрегированный столбец 'Houses.availabilitydata.arrival', которыйфункционально не зависит от столбцов в предложении GROUP BY;это несовместимо с sql_mode = only_full_group_by

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

Как я могу ограничитьэто одна строка на дом, а именно строка, из которой получается min ((pergroup + (perguest * GREATEST ((2 - guest_included), 0)))).

таблиц:

create table availabilitydata
(
  arrival              date        not null,
  departure            date        not null,
  housecode            varchar(32) not null,
  pergroup             float       null,
  pergroupexcldiscount float       null,
  perguest             float       null,
  guests_included      tinyint     null,
  primary key (housecode, arrival, departure)
);

create table housedata
(
  housecode       varchar(32) not null
    primary key,
  name            tinytext    null
);

Данные должны быть такими, но с добавленным столбцом даты:

344323  Wienerwaltz 680.530029296875
434300  Wald    882.7899780273438
943843  Chalet Miquel   630.8300170898438

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Попробуйте следующим образом:

select h.housecode
     , hh.name
     , pergroup + (perguest *  GREATEST((2 - guests_included),0)) as mincalculated
     -- select any column from a (availabilitydata)
from housedata h
inner join availabilitydata a on a.housecode = h.housecode 
where (a.housecode, a.arrival, a.departure) = (
    select a2.housecode, a2.arrival, a2.departure
    from availabilitydata a2
    where a2.housecode = h.housecode
      and datediff(a2.departure, a2.arrival) = 7
    order by a2.pergroup + (a2.perguest *  GREATEST((2 - a2.guests_included),0)) asc
    limit 1
)

В коррелированном подзапросе вы получите первичный ключ (a.housecode, a.arrival, a.departure) строки с минимальным вычисленным значением.Во внешнем запросе вы выбираете только строку из availabilitydata с тем же первичным ключом.

Обратите внимание, что если две строки имеют одинаковое вычисленное минимальное значение, вы получите обе из них.Если вам не нужны оба, вы должны определить, какой из них вы хотите в предложении ORDER BY (например, добавив полный первичный ключ):

order by a2.pergroup + (a2.perguest *  GREATEST((2 - a2.guests_included),0)) asc
    , a2.arrival
    , a2.departure

Обновление

Приведенное выше решение неКажется, не очень хорошо.Но если ваша версия поддерживает оконные функции, вы также можете использовать следующий запрос:

select *
from (
    select housedata.housecode
         , housedata.name
         , pergroup + (perguest *  GREATEST((2 - guests_included),0)) as mincalculated
         , row_number() over (
             partition by housedata.housecode
             order by pergroup + (perguest *  GREATEST((2 - guests_included),0)) asc
         ) rn
         , availabilitydata.arrival
         -- select any other column from availabilitydata
    from housedata
    inner join availabilitydata on housedata.housecode = availabilitydata.housecode 
    where datediff(departure, arrival) = 7
) x
where rn = 1
0 голосов
/ 02 марта 2019

Вам необходимо использовать статистическую функцию для столбцов (полей), которые вы добавляете в SQL: те, которые не агрегированы, должны (в стандартном SQL, но mySQL в любом случае принимать SQL, в зависимости от настройки sql_mode) быть перечислены встолбцы GROUP BY.

В заключение, если вы хотите добавить availabilitydata столбцы таблицы и не обращаете внимания на то, какие из нескольких записей в одной группе отображаются, следует использовать MIN(availabilitydata.col1), MIN(availabilitydata.col2), ... и всегда перечислятьвсе неагрегированные столбцы в выражении GROUP BY:

select housedata.housecode, 
       housedata.name,
       min(availabilitydata.col1) as  availabilitydata_col1_min,
       min(availabilitydata.col2) as  availabilitydata_col2_min,
       ...,
       min((pergroup + (perguest *  GREATEST((2 - guests_included),0)))) as mincalculated 
from housedata
inner join availabilitydata 
where housedata.housecode = availabilitydata.housecode 
and  datediff(departure, arrival) = 7 
group by housedata.housecode,housedata.name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...