Reputation: 3
I have a CREATE VIEW query in hsql, but whenever I run it, it throws me this error:
expression not in aggregate or GROUP BY columns: AGV.ID
I understand that GROUP BY would not work without any aggregate expressions(AVG, SUM, MIN, MAX), but I can't figure out how to fix my query.. because each record needs to be grouped by manifestID value.
Basically, im trying to create a VIEW by combining 3 sets of select queries.
I tried to use distinct but no luck, since it will not work if i have multiple selected columns. This query works fine in MYSQL.
My Query:
CREATE VIEW local_view_event_manifest(
manifest_id,
eventId,
eventType,
eventDate,
manifestID,
businessStepStr,
manifestVersion,
externalLocation,
remark,
epcCode,
locationCode
)
AS
SELECT
agm.manifest_id AS manifest_id,
agv.id AS eventId,
'AGGREGATION_EVENT' AS eventType,
agv.event_time AS eventDate,
md.manifest_id AS manifestID,
agv.business_step_code AS businessStepStr,
md.manifest_version AS manifestVersion,
md.external_location AS externalLocation,
md.remark AS remark,
epc.code as epcCode,
bloc.location_code as locationCode
FROM
"local".local_MANIFEST_DATA AS md,
"local".local_AGGREGATION_EVENT AS agv,
"local".local_AGGREGATION_EVENT_EPCS AS agv_epc,
"local".local_EPC AS epc,
"local".local_BUSINESS_LOCATION AS bloc,
"local".local_AGGREGATION_EVENT_MANIFEST_DATA AS agm
WHERE
md.id=agm.manifest_id
AND agv.deleted=0
AND md.deleted=0
AND agv.id=agm.aggregation_event_id
AND agv.id=agv_epc.aggregation_event_id
AND agv.business_location_id=bloc.id
AND bloc.id=agv.business_location_id
AND agv_epc.epc_id=epc.id
GROUP BY agm.manifest_id
UNION
SELECT
om.manifest_id AS manifest_id,
ov.id AS eventId,
'OBJECT_EVENT' AS eventType,
ov.event_time AS eventDate,
md.manifest_id AS manifestID,
ov.business_step_code AS businessStepStr,
md.manifest_version AS manifestVersion,
md.external_location AS externalLocation,
md.remark AS remark,
epc.code as epcCode,
bloc.location_code as locationCode
FROM
"local".local_MANIFEST_DATA AS md,
"local".local_OBJECT_EVENT AS ov,
"local".local_OBJECT_EVENT_EPCS AS ov_epc,
"local".local_EPC AS epc,
"local".local_BUSINESS_LOCATION AS bloc,
"local".local_OBJECT_EVENT_MANIFEST_DATA AS om
WHERE
md.id=om.manifest_id
AND ov.deleted=0
AND md.deleted=0
AND ov.id=ov_epc.object_event_id
AND ov.id=om.object_event_id
AND bloc.id=ov.business_location_id
AND ov_epc.epc_id=epc.id
GROUP BY om.manifest_id
UNION
SELECT
trm.manifest_id AS manifest_id,
trv.id AS eventId,
'TRANSACTION_EVENT' AS eventType,
trv.event_time AS eventDate,
md.manifest_id AS manifestID,
trv.business_step_code AS businessStepStr,
md.manifest_version AS manifestVersion,
md.external_location AS externalLocation,
md.remark AS remark,
epc.code as epcCode,
bloc.location_code as locationCode
FROM
"local".local_MANIFEST_DATA AS md,
"local".local_TRANSACTION_EVENT AS trv,
"local".local_TRANSACTION_EVENT_EPCS AS trv_epc,
"local".local_EPC AS epc,
"local".local_BUSINESS_LOCATION AS bloc,
"local".local_TRANSACTION_EVENT_MANIFEST_DATA AS trm
WHERE
md.id=trm.manifest_id
AND trv.deleted=0
AND md.deleted=0
AND trv.id=trv_epc.transaction_event_id
AND trv.id=trm.transaction_event_id
AND bloc.id=trv.business_location_id
AND trv_epc.epc_id=epc.id
GROUP BY trm.manifest_id
below are snapshots of query results in mysql using GROUP BY & without GROUP BY:
T
@fredt... thanks for the detailed explanation.. referring to your suggestion, i've tried it.. but somehow im getting this error:
ERROR: Table not found: TABL_B in statement [SELECT TABL_B.* FROM (SELECT DISTINCT manifest_id FROM "local".local_AGGREGATION_EVENT_MANIFEST_DATA) TABL_A ] Error Code: -22
Below is my query:
SELECT TABL_B.* FROM (SELECT DISTINCT manifest_id FROM "local".local_AGGREGATION_EVENT_MANIFEST_DATA) TABL_A
LATERAL JOIN
( SELECT
agm.manifest_id AS manifest_id,
agv.id AS eventId,
'AGGREGATION_EVENT' AS eventType,
agv.event_time AS eventDate,
md.manifest_id AS manifestID,
agv.business_step_code AS businessStepStr,
md.manifest_version AS manifestVersion,
md.external_location AS externalLocation,
md.remark AS remark,
epc.code as epcCode,
bloc.location_code as locationCode
FROM
"local".local_MANIFEST_DATA AS md,
"local".local_AGGREGATION_EVENT AS agv,
"local".local_AGGREGATION_EVENT_EPCS AS agv_epc,
"local".local_EPC AS epc,
"local".local_BUSINESS_LOCATION AS bloc,
"local".local_AGGREGATION_EVENT_MANIFEST_DATA AS agm
WHERE
md.id=agm.manifest_id
AND agv.deleted=0
AND md.deleted=0
AND agv.id=agm.aggregation_event_id
AND agv.id=agv_epc.aggregation_event_id
AND agv.business_location_id=bloc.id
AND bloc.id=agv.business_location_id
AND agv_epc.epc_id=epc.id AND manifest_id = TABL_A.manifest_id LIMIT 1 ) TABL_B
thanks @fredt.. i noticed on the comma thing and already added to my query. and i tried removing the JOIN word also. But still throwing same error..
ERROR: Table not found in statement [SELECT TABL_B.* FROM (SELECT
DISTINCT MANIFEST_ID FROM "local".local_AGGREGATION_EVENT_MANIFEST_DATA)
AS TABL_A, LATERAL] Error Code: -22
Upvotes: 0
Views: 9332
Reputation: 24352
With HSQLDB 2.2.x or later:
When you use GROUP BY, all your selected columns must be in the GROUP BY list, except any column that is an aggregate. In your example, the GROUP BY list should contain 11 columns, not one column.
You can use DISTINCT, as in SELECT DISTINCT COL1, COLB, COLC, ...
without group by. DISTINCT is a shortcut for grouping all the columns in the SELECT list.
In general, GROUP BY means the query should return one row only for each combination of column values in the GROUP BY list. Aggregates are allowed as they combine values from possibly multiple rows into one value.
Now if you include all the columns in the GROUP BY list and the result has multiple rows with the same manifestID value, it means you cannot really group on manifestID alone.
Update: Your query results with MySQL show it is not very strict in this area. There are over twenty rows with manifestId=bhbhbhbh and the values in other columns are not the same. Yet MySQL returns one of the rows randomly. This is not how GROUP BY works according to the SQL Standard supported by other databases, including HSQLDB. See this blog by a MySQL expert:
http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/
If you want something like the MySQL output, then you need queries like this:
SELECT TABL_B.* FROM (SELECT DISTINCT manifestID FROM "local".local_AGGREGATION_EVENT_MANIFEST_DATA) TABL_A,
LATERAL
( [YOUR SELECT STATEMENT WITHOUT GROUP BY] AND manifestID = TABL_A.manifestID LIMIT 1 ) TABL_B
Try with one of the selects in the VIEW first, then apply to the rest.
You can choose which one of the rows is returned by adding an ORDER BY COL_NAME before LIMIT 1.
Upvotes: 2