У меня есть такой запрос в моей программе:
SELECT customer.Id, customer.FirstName, customer.LastName, SUM(PeriodHours) AS SUMPeriodHours, PeriodDay
FROM (
(SELECT CustomerId,
(UNIX_TIMESTAMP(taskinterval.EndDateUtc) - UNIX_TIMESTAMP(taskinterval.StartDateUtc)) / 3600 AS PeriodHours,
date(taskinterval.StartDateUtc) as PeriodDay
FROM taskinterval
WHERE StartDateUtc > @STARTDATE and StartDateUtc<@ENDDATE
) AS tmptbl
)
INNER JOIN customer on customer.Id = tmptbl.CustomerId
GROUP BY PeriodDay, customer.Id, customer.FirstName, customer.LastName
Это не работает ни в коде моей программы, ни в SqlWorkbench, когда я заменяю «@ENDDATE» и «@STARTDATE».
Он отлично работает в MariaDB 10.3.32, но в MySQL 8.0.35 не работает, отображается такая ошибка:
Код ошибки: 1064. У вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, чтобы найти правильный синтаксис для использования рядом с ') Внутреннее присоединение клиента к клиенту.Id = tmptbl.CustomerId group'
Эта ошибка кажется мне неясной. Я просмотрел эту статью: https://mariadb.com/kb/en/incompatabilities-and-feature-differences-between-mariadb-10-4-and-mysql-8-/, но ничего не нашел это может помочь мне с этим вопросом. Как исправить этот запрос, чтобы сделать его совместимым с MySQL?
Почему это закрыли? Разве будущим читателям не важно знать, что у MySQL есть проблема с дополнительными круглыми скобками, которые другие СУБД считают только излишними? Я проголосовал за то, чтобы это снова открылось.
Если у MySQL есть какие-либо проблемы с этими круглыми скобками, действительно ли это связано с программированием?
@Нико Хаазе: Да, это так. Различные СУБД имеют разные диалекты SQL. Некоторые позволяют группировать по псевдонимам, другие — нет. Таким образом, если кто-то попытается сгруппировать по псевдониму, и его СУБД выдаст ошибку, он найдет ответ на stackoverflow, что некоторые СУБД поддерживают синтаксис, а их нет. То же самое. Обычно СУБД справляются с дополнительными круглыми скобками, но MySQL здесь особенный. Если программист наткнется на эту ошибку, он будет рад найти объяснение в stackoverflow, потому что я почти уверен, что это трудно найти в документации MySQL, если вообще найти.
Псевдоним tmptbl находится в неправильном положении. Должно быть после производной таблицы. (Т.е. после последней закрывающей правой скобки.) В соответствии со стандартом ISO/ANSI SQL!


Кажется, у вас есть лишняя скобка. Попробуй это
Select
customer.Id,
customer.FirstName,
customer.LastName,
SUM(PeriodHours) as SUMPeriodHours,
PeriodDay
from
(
SELECT
CustomerId,
(
UNIX_TIMESTAMP(taskinterval.EndDateUtc) - UNIX_TIMESTAMP(taskinterval.StartDateUtc)
) / 3600 as PeriodHours,
date(taskinterval.StartDateUtc) as PeriodDay
FROM
taskinterval
where
StartDateUtc > @STARTDATE
and StartDateUtc < @ENDDATE
) as tmptbl
Inner Join customer on customer.Id = tmptbl.CustomerId
group by
PeriodDay,
customer.Id,
customer.FirstName,
customer.LastName
Непосредственной причиной является дополнительная ( .. ):
FROM (( SELECT ... FROM taskinterval))
должен быть
FROM ( SELECT ... FROM taskinterval)
Чтобы избежать таких досадных ошибок, сделайте запрос простым, разбейте его на легко читаемые фрагменты, в вашем случае CTE:
WITH tmptbl AS (
SELECT CustomerId,
(UNIX_TIMESTAMP(taskinterval.EndDateUtc) - UNIX_TIMESTAMP(taskinterval.StartDateUtc)) / 3600 AS PeriodHours,
date(taskinterval.StartDateUtc) AS PeriodDay
FROM taskinterval
WHERE StartDateUtc > @STARTDATE AND StartDateUtc < @ENDDATE
)
SELECT customer.Id,
customer.FirstName,
customer.LastName,
SUM(PeriodHours) AS SUMPeriodHours,
PeriodDay
FROM tmptbl
JOIN customer ON customer.Id = tmptbl.CustomerId
GROUP BY customer.Id,
customer.FirstName,
customer.LastName,
PeriodDay
Этот код используется в программе на C#. Сомневаюсь, что вы можете упаковать ДВА запроса в вызов MySqlCommand. Хотя выглядит аккуратно
@Иван П.: обратите внимание, что это один запрос (который можно выполнить как обычно). Близкая аналогия: у нас может быть одна программа с несколькими методами (не один огромный Main)
@ИванП. Это разрешено, см. dev.mysql.com/doc/connector-net/en/… опция AllowBatch
Дополнительный ( ... ) разрешен, если он не использует псевдоним таблицы. Это используется для группировки операций над множествами, таких как UNION и INTERSECT. dbfiddle.uk/a5Esl2So
Да, я вижу, что FROM (( SELECT ... )) AS tmptbl ) работает на MySQL 8.9.36.
Что не так с синтаксисом SQL моего запроса? Лишняя скобка, которая оборачивает подзапрос (закрывающая скобка, которая начинает фрагмент кода в сообщении об ошибке, и соответствующая открывающая скобка). В MySQL это означает «преобразовать выходные данные подзапроса в скалярное значение». Удалить их.