Search code examples
postgresqlpostgresql-9.3

How to fix syntax errors on GROUP BY clause when converting MySQL to PostgreSQL


I'm converting a series of queries from MySQL to PostgreSQL to run on a particular Moodle instance. I'm no expert in either language by any stretch, which leaves me rather complexed as to why PostgreSQL is throwing a syntax error on my GROUP BY clause. How do I create the GROUP BY clause correctly?

I've looked at other answers on StackOverflow that mention that the GROUP BY clause requires listing all columns in the SELECT statement. I've added the other columns to the GROUP BY clause (see commented out code below). However, the same issue remains.

This is run within a SQL report tool on a Moodle application (db structure here: https://moodleschema.zoola.io/index.html).

-- valid MySQL query. This query selects the course name, counts the times the course has been accessed within the last 12 months and displays it in a table IF it is a visible course.
SELECT c.fullname, count(course) AS actions, course AS courseid, c.visible AS visibility
FROM prefix_log l, prefix_course c
WHERE l.course = c.id
  AND c.visible = 1
  AND time BETWEEN unix_timestamp(date_sub(Now(), INTERVAL 12 MONTH)) AND unix_timestamp(Now())
  AND c.id != 1
GROUP BY course
ORDER BY actions DESC
--postgreSQL conversion attempt
SELECT c.fullname, count(course) AS actions, course AS courseid, c.visible AS visibility
FROM prefix_log l, prefix_course c
WHERE l.course = c.id
  AND c.visible = 1
  AND extract(epoch from NOW()) BETWEEN extract(epoch from NOW()- INTERVAL '12 months') AND to_date(NOW()::TEXT
  AND c.id != 1
GROUP BY course
-- Query failed
--
-- ERROR:  syntax error at or near "GROUP"
-- LINE 7: GROUP BY course
--         ^
-- When using the 'GROUP BY course, actions, c.fullname, c.visible' clause:
-- Query failed
--
-- ERROR:  syntax error at or near "GROUP"
-- LINE 8: GROUP BY course, actions, c.fullname, c.visible
--         ^
ORDER BY actions DESC

I expect that my conversion attempt from MySQL to PostgreSQL is valid and returns a list of active courses within the last 12 months, but I cannot validate my conversion attempt.

EDIT: SOLUTION @Jeremy has noted that I was missing a closing parenthesis in the 12-month clause in the WHERE statement. I've also fixed some resultant minor errors in my code as well - see below.

SELECT c.fullname as CourseName, COUNT(course) AS actions, course AS courseid, c.visible AS visibility
FROM prefix_log l, prefix_course c
WHERE l.course = c.id
  AND c.visible = 1
  AND extract(epoch from NOW()) BETWEEN extract(epoch from NOW()- INTERVAL '12 months') AND extract(epoch from NOW())
  AND c.id != 1
GROUP BY course, c.fullname, c.visible
ORDER BY actions DESC

Solution

  • This line is missing a closing parenthesis:

    AND extract(epoch from NOW()) BETWEEN extract(epoch from NOW()- INTERVAL '12 months') AND to_date(NOW()::TEXT
    

    It also doesn't make any sense, but the syntax error is did to the missing closing parenthesis.

    Now will always be between now and twelve months ago. Casting now to text and converting to a date is an extra step at best, but you are clearly missing some part of the logic after that.