Выберите в MySQL, где все строки удовлетворяют условию

Эта ошибка была вызвана отсутствием секции build в файле pom.xml. Среди прочего, этот раздел идентифицирует основной класс проекта. Очевидно, Eclipse не может правильно запустить проект без этой информации. Вот раздел build, соответствующий проекту, описанному выше:

<build>
 <plugins>
  <plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>exec-maven-plugin</artifactId>
   <version>1.1.1</version>
   <executions>
    <execution>
     <phase>test</phase>
     <goals>
      <goal>java</goal>
     </goals>
     <configuration>
      <mainClass>org.ldesousa.Transformation</mainClass>
     </configuration>
    </execution>
   </executions>
  </plugin>
 </plugins>
</build>

Обратите внимание, что мне пришлось включить основной пакет (org.ldesousa в данном случае).

6
задан O. Jones 14 June 2013 в 13:39
поделиться

4 ответа

Ответы от @jjclarkson и @davethegr8 близки, но Вы не можете поместить агрегатные функции в оператор Where. Оператор Where оценен для каждой строки.

Необходимо оценить MAX() выражение для каждой группы, таким образом, необходимо использовать a HAVING пункт.

Попробуйте это:

SELECT UserID 
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';

@MBCook комментирует это HAVING может быть медленным. Вы правы, это не мог бы быть абсолютный самый быстрый способ привести к желаемому результату. Но HAVING решение является самым ясным. Существуют ситуации, где производительность имеет более низкий приоритет, чем ясность и пригодность для обслуживания.

Я смотрел на ОБЪЯСНИТЬ вывод (на MySQL 5.1.30) для HAVING решение: никакие индексы не использовались, и дополнительные сказанные примечания"Using temporary; Using filesort," который обычно означает, что производительность будет плоха.

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

SELECT DISTINCT a1.UserID
FROM ArrivalTimes a1
  LEFT OUTER JOIN ArrivalTimes a2 
  ON (a1.UserID = a2.UserID AND a2.ArrivalTime > '09:00:00')
WHERE a2.UserID IS NULL;

Это генерирует план оптимизации, который использует индекс на UserID и говорит:

  • a1:"Using index; Using temporary"
  • a2:"Using where; Distinct"

Наконец, следующий запрос генерирует план оптимизации, который, кажется, использует индексы наиболее эффективно, и никакие временные таблицы или filesort.

SELECT DISTINCT a1.UserID
FROM ArrivalTimes a1
WHERE NOT EXISTS (SELECT * FROM ArrivalTimes a2 
                  WHERE a1.UserID = a2.UserID 
                    AND a2.ArrivalTime > '09:00:00'); 
  • a1:"Using where; Using index"
  • a2:"Using where"

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

18
ответ дан 8 December 2019 в 05:58
поделиться

Билл Карвин предлагает:

Попробуйте:

SELECT UserID 
FROM ArrivalTimes
GROUP BY UserID
HAVING MAX(ArrivalTime) <= '09:00:00';

Я посмотрел на вывод EXPLAIN (в MySQL 5.1.30) для решения HAVING: индексы не использовались, и дополнительные примечания сказал: «Использование временного; Использование файловой сортировки», что обычно означает, что производительность будет низкой.

Я бы сказал, что следующее еще яснее, учитывая, что есть пользовательская таблица, для которой ArrivalTimes.UserId является внешним ключом. Это выбирает всех никогда не запаздывающих пользователей:

 select * from user a 
 where '09:00:00' 
  >= all( select ArrivalTime from ArrivalTime b where b.UserID = a.ID);

Это выбирает любого пользователя, который когда-либо запаздывал:

 select * from user a 
 where '09:00:00' 
  < any( select ArrivalTime from ArrivalTime b where b.UserID = a.ID);

Это более понятно, потому что оно еще более близко соответствует нашей спецификации английского / естественного языка.

И это позволяет избежать неэффективности группа по ; под MySql 5.0.51 он не требует временной или файловой сортировки, как это делает Билл.

(Обратите внимание, что требуется, чтобы значение постоянного времени было дополнено нулями, таким образом: '09: 00: 00 '; «9:00:00» не удается.)

1
ответ дан 8 December 2019 в 05:58
поделиться

Это было хорошей мыслью, но она не работает.

SELECT UserID FROM ArrivalTimes WHERE MAX(ArrivalTime) <= '09:00:00' GROUP BY UserID

С этим запросом Вы получите ошибку при высказывании: "Недопустимое использование функции группы"

Агрегатные функции как КОЛИЧЕСТВО, МАКС, МИН, AVG, СУММА и другие по определению выполняют свою функцию на наборе (или группа записей), таким образом, МАКС (ArrivalTime) должен быть в форме:

GROUP BY UserID HAVING MAX(ArrivalTime) <= '09:00:00'

См. ответ от @Bill Karwin выше.

1
ответ дан 8 December 2019 в 05:58
поделиться
SELECT userID, MAX(ArrivalTime) as latest
FROM ArrivalTimes 
WHERE latest <= '9:00:00'
GROUP BY userID
1
ответ дан 8 December 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: