POSTGRES Group by / Inner Join - sql

I am having problems writing a query to summarize the number trips from a OD matrix table. I am still new to using databases other than MS Access, so please forgive my inexperience. SMGZ is the table with the number of zones and matrix_od is the matrix table with all the OD pairs(4109*4109) from zone to zone with the total number of trip types. I am not sure this is the best way to write this query. SO what i need to do is summarize 4 types of trips(LHDT,MHDT,HHDT,HDT_Tota) by the OD. Help is much appreciated.
SELECT
smgz.smg_zone AS "O_ID",
smgz.x AS "O_X",
smgz.y AS "O_Y",
smgz1.smg_zone AS "D_ID",
smgz1.x AS "D_X",
smgz1.y AS "D_Y",
SUM(matrix_od."LHDT") AS "LHDT_Tot",
SUM(matrix_od."MHDT") AS "MHDT_Tot",
SUM(matrix_od."HHDT") AS "HHDT_Tot",
SUM(matrix_od."TOT_HDT") AS "HDT_Tot"
FROM
public.smgz,
public.matrix_od,
public.smgz smgz1
GROUP BY
"O_ID","O_X","O_Y","D_ID","D_X","D_Y"
INNER JOIN
smgz on matrix_od.O_ID = smgz.ID
INNER JOIN
smgz1 on matrix_od.D_ID = smgz1.ID;
ERROR: syntax error at or near "INNER"
LINE 18: INNER JOIN
^
********** Error **********
ERROR: syntax error at or near "INNER"
SQL state: 42601
Character: 414

As stated in comments the two main errors are that the group by clause is in the wrong place, it should be after the joins, and that you are mixing implicit joins (multiple tables in the from clause) with explicit joins (using the join keyword). The fix is to change this part:
FROM
public.smgz,
public.matrix_od,
public.smgz smgz1
GROUP BY
"O_ID","O_X","O_Y","D_ID","D_X","D_Y"
INNER JOIN
smgz on matrix_od.O_ID = smgz.ID
INNER JOIN
smgz1 on matrix_od.D_ID = smgz1.ID;
to this:
FROM
public.matrix_od
INNER JOIN
public.smgz on matrix_od.O_ID = smgz.ID
INNER JOIN
public.smgz smgz1 on matrix_od.D_ID = smgz1.ID
GROUP BY
"O_ID","O_X","O_Y","D_ID","D_X","D_Y";

That did the trick! Thank you #a_horse_with_no_name & #Lamak.
SELECT
smgz.smg_zone AS "O_ID",
smgz.x AS "O_X",
smgz.y AS "O_Y",
smgz1.smg_zone AS "O_ID",
smgz1.x AS "D_X",
smgz1.y AS "D_Y",
SUM(matrix_od."LHDT") AS "LHDT_Tot",
SUM(matrix_od."MHDT") AS "MHDT_Tot",
SUM(matrix_od."HHDT") AS "HHDT_Tot",
SUM(matrix_od."TOT_HDT") AS "HDT_Tot"
FROM
public.matrix_od
INNER JOIN
smgz on matrix_od."O_ID" = smgz."id"
INNER JOIN
public.smgz smgz1 on matrix_od."D_ID" = smgz1."id"
GROUP BY
smgz.smg_zone,smgz.x,smgz.y,smgz1.smg_zone,smgz1.x,smgz1.y;

Related

'or' operator in left join

select
evm.case_id, evm.close_ts, evm.cm_promise_utc_ts, evm.cm11, evm.cm13, evm.creat_id, evm.creat_ts, evm.creat_type,
evm.event_act, evm.event_act_perf, evm.event_dt, evm.event_id, evm.event_orig, evm.event_srce, evm.event_sta, evm.event_sub_type, evm.event_type,
evm.fol_pref_mthd, evm.incdnt_no,
evm.lst_updt_id, evm.lst_updt_ts, evm.lst_updt_type,
evm.main_sta, evm.new_act_note, evm.orig_id, evm.own_type, evm.prod_type, evm.req_chan, evm.srvc_arm,
crm.case_nm,
evg.req_add_info as req_add_info_general, evg.rslt_add_info,
evt.add_info, evt.other_ds, evt.req_add_info as req_add_info_ticketing,
eve.event_iss, eve.event_rev,
eve.req_cm_commentary, eve.req_event_nm, eve.rslt_err_dt, eve.rslt_root_cause, eve.rslt_rslv_dtl_cnfr, eve.rslt_rslv_dtl_outcm,
tlsopus.agnt_emply_sta, tlsopus.dlvr_mthd, tlsopus.dm_ctry,
tlsopus.event_subtype as event_sub_type_tlsarpt,
tlsopus.mkt_alpha_cd, tlsopus.own_id, tlsopus.prod_full_nm,
tlsopus.repr_locat, tlsopus.req_pref_spec_dt, tlsopus.req_vend, tlsopus.rslt_rec_loctr,
tlsopus.trvl_prod, tlsopus.trvl_type, tlsopus.user_role,
tlssales.trip_id, tlssales.inv_dt, tlssales.refd_exch_in,
tlssales.trip_type, tlssales.trans_usd_am, tlssales.mkt_cd, tlssales.chan_type,tlssales.exp_trip_id
from cstonedb3.opus_event_master as evm
left join cstonedb3.opus_crm_cases as crm
on evm.case_id = crm.case_id
left join cstonedb3.opus_event_general as evg
on evm.event_id = evg.event_id
left join cstonedb3.opus_event_ticketing as evt
on evm.event_id = evt.event_id
left join cstonedb3.opus_event_escalation as eve
on evm.event_id = eve.event_id
left join cstonedb3.tlsarpt_opus_case_detail as tlsopus
on evm.event_id = tlsopus.event_id
left join cstonedb3.tlsarpt_travel_sales as tlssales
on tlsopus.rslt_rec_loctr = tlssales.trip_id
or tlsopus.rslt_rec_loctr = tlssales.exp_trip_id
where evm.creat_ts between '2022-07-01' and '2022-07-31'
and tlsopus.mkt_alpha_cd = 'US';
tlssales table has two columns that correspond to one column in tlsopus
i.e the values for "tlsopus.rslt_rec_loctr" can be present in either "tlssales.trip_id" or "tlssales.exp_trip_id".
I want the join to first search through the "tlssales.trip_id" column. If there's no match here in this column, then look for a match in "tlssales.exp_trip_id" column.
For this I applied the or condition in the last join statement. But this query gives the following error :
FAILED: SemanticException Cartesian products are disabled for safety
reasons. If you know what you are doing, please
sethive.strict.checks.cartesian.product to false and that
hive.mapred.mode is not set to 'strict' to proceed. Note that if you
may get errors or incorrect results if you make a mistake while using
some of the unsafe features.
Can someone please explain where I'm going wrong? I tried to look through other pages and found out that we can apply or in join.

Error -- SQL Compilation Error: syntax error line 1 at position 0 unexpected 'INNER'

I am trying to perform an inner join on two tables by date and county ID. Whenever I run the query, I get the following error:
SQL Compilation Error: syntax error line 1 at position 0 unexpected 'INNER'
The code is as follows:
SELECT
ISO3166_1,
FIPS,
DATE,
CASES
FROM
"covid-19","public"."timeseries"
WHERE
ISO3166_1 = 'US'
INNER JOIN
"db"."population_schema"."pop_table"
ON
(("covid-19","public"."timeseries".fips = "db"."population_schema"."pop_table".fips)
AND
("covid-19","public"."timeseries".date= "db"."population_schema"."pop_table".date))
For reference, the date and FIPS data types are the same. Are there any glaringly obvious issues?
The WHERE clauses go after all JOINS:
SELECT
ISO3166_1,
FIPS,
DATE,
CASES
FROM "covid-19","public"."timeseries" AS a
INNER JOIN "db"."population_schema"."pop_table" AS b
ON a.fips = b.fips
AND a.date= b.date
WHERE
ISO3166_1 = 'US'
and if you alias those two tables, your join logic can be much more readable.

MS Access INNER JOIN/LEFT JOIN problems

I have the following SQL string which tries to combine an INNER JOIN with a LEFT JOIN in the FROM section.
As you can see I use table VIP_APP_VIP_SCENARIO_DETAIL_LE to perform the query. When I use it against this table, Access give me an "Invalid Operation" error.
Interestingly, when I use the EXACT same query using the VIP_APP_VIP_SCENARIO_DETAIL_BUDGET or VIP_APP_VIP_SCENARIO_DETAIL_ACTUALS table, it performs flawlessly.
So why would it work on two tables but not the other? All fields are in all tables and the data types are correct.
As a side note: on the query with the error, if I change the LEFT JOIN to an INNER JOIN, it runs with no problem! I really need a LEFT JOIN though.
SELECT
D.MATERIAL_NUMBER,
D.MATERIAL_DESCRIPTION,
D.PRODUCTION_LOT_SIZE,
D.STANDARDS_NAME,
D.WORK_CENTER,
S.OP_SHORT_TEXT,
S.OPERATION_CODE,
D.LINE_SPEED_UPM,
D.PERCENT_STD,
D.EQUIPMENT_SU,
D.EQUIPMENT_CU,
D.OPERATOR_NUM,
V.COSTING_LOT_SIZE,
V.VOL_TOTAL_ADJ
FROM
([STDS_SCENARIO: TEST] AS D INNER JOIN MASTER_SUMMARY AS S ON
D.MATERIAL_NUMBER = S.MATERIAL_NUMBER AND D.WORK_CENTER = S.WORK_CENTER)
LEFT JOIN
(SELECT ITEM_CODE, COSTING_LOT_SIZE, VOL_TOTAL_ADJ
FROM
VIP_APP_VIP_SCENARIO_DETAIL_LE
WHERE SCENARIO_ID = 16968) AS V ON D.MATERIAL_NUMBER = V.ITEM_CODE
ORDER BY D.MATERIAL_NUMBER, D.STANDARDS_NAME, S.OPERATION_CODE;
tried to mock this up in SQL server with some tables of my own, but the structure seemed to work, this follows the pattern referenced above. (hopefully no syntax errors left here)
SELECT * FROM (
select
D.MATERIAL_NUMBER,
D.MATERIAL_DESCRIPTION,
D.PRODUCTION_LOT_SIZE,
D.STANDARDS_NAME,
D.WORK_CENTER,
S.OP_SHORT_TEXT,
S.OPERATION_CODE,
D.LINE_SPEED_UPM,
D.PERCENT_STD,
D.EQUIPMENT_SU,
D.EQUIPMENT_CU,
D.OPERATOR_NUM
FROM [STDS_SCENARIO: TEST] D
INNER JOIN MASTER_SUMMARY S
ON D.MATERIAL_NUMBER = S.MATERIAL_NUMBER AND D.WORK_CENTER = S.WORK_CENTER) AS J
LEFT JOIN
(SELECT ITEM_CODE, COSTING_LOT_SIZE, VOL_TOTAL_ADJ
FROM
VIP_APP_VIP_SCENARIO_DETAIL_LE
WHERE SCENARIO_ID = 16968) AS V ON J.MATERIAL_NUMBER = V.ITEM_CODE
ORDER BY J.MATERIAL_NUMBER, J.STANDARDS_NAME, J.OPERATION_CODE;
Had help from a friend and we discovered that it was a casting problem between a linked Oracle table and the Access table. To fix the problem we casted both sides of the linked fields to a string:
CSTR(D.[MATERIAL_NUMBER]) = CSTR(V.[ITEM_CODE])

What is difference between 2 sql queries?

I have 2 sql queries one of them work but the other gives error. Following query works well
select /*ordered*/ coupon_address.coupon,merchant_address.id
from merchant_address,
coupon_address,
customers c
WHERE merchant_address.id = coupon_address.merchant_address
and c.CUSTOMER_ID = 'temp1'
AND sdo_within_distance(c.cust_geo_location,merchant_address.store_geo_location,'distance = 1 unit=MILE') = 'TRUE';
But following query doesn't work and gives an error
select /*ordered*/ coupon_address.coupon,merchant_address.id
from coupon_address,
customers c
JOIN merchant_address ON merchant_address.id=coupon_address.merchant_address
WHERE c.CUSTOMER_ID = 'temp1'
AND sdo_within_distance (c.cust_geo_location,merchant_address.store_geo_location, 'distance = 1 unit=MILE') = 'TRUE';
Error is
ERROR at line 1: ORA-00904: "COUPON_ADDRESS"."MERCHANT_ADDRESS": invalid identifier
Don't ever mix explicit and implicit join syntax together! They will always lead to confusion and errors :
select /*ordered*/ coupon_address.coupon,merchant_address.id
FROM coupon_address
JOIN merchant_address
ON merchant_address.id=coupon_address.merchant_address
JOIN customers c ON c.CUSTOMER_ID = 'temp1'
WHERE sdo_within_distance (c.cust_geo_location,
merchant_address.store_geo_location,
'distance = 1 unit=MILE') = 'TRUE';
The reason it didn't work is the order that the parser evaluates the query. Probably the unknown column's table wasn't evaluated yet.
The JOIN has a higher precedence than the , in the FROM clause. ON is part of the JOIN so it only sees that which begin joined, including earlier joins.
So:
select /*ordered*/ coupon_address.coupon,merchant_address.id
from coupon_address,
customers c
JOIN merchant_address
ON merchant_address.id=coupon_address.merchant_address
is in essence:
select /*ordered*/ coupon_address.coupon,merchant_address.id
from coupon_address,
(customers c
JOIN merchant_address
ON merchant_address.id=coupon_address.merchant_address)
and coupon_address is not yet in scope.
As others have said, best to stick to one style of joins, either SQL-92 join keywords or the earlier commas in the from clause and join criteria in the where clause. I prefer the explicit join syntax.
Sagi's answer is correct. The reason your version doesn't work is because of the scoping rules around commas in the FROM clause. Oh, did I mention: Never use commas in the FROM clause. Always use explicit JOIN syntax.
Your FROM clause is evaluated as:
from coupon_address,
(customers c JOIN
merchant_address
ON merchant_address.id = coupon_address.merchant_address
)
I think this makes it obvious why you are getting the error.

Why does the Inner Join query not work while multi where clause does

Lets say I run a crooked car company. Let's say I have the following table:
car_engine_mileage_counters which is a join table from car_engines onto mileage_counters also storing a calculated field of mileage
Lets also say that I encode a coefficient at the engine block level in my factory on an engine template.
UPDATE car_engine_mileage_counters
SET mileage = mileage_counters.mileage * coefficients.coefficient
FROM car_engines
INNER JOIN engine_templates
ON car_engines.template_id = engine_templates.id
INNER JOIN mileage_counters
ON mileage_counters.id = car_engine_mileage_counters.mileage_counter_id
INNER JOIN mileage_counter_templates
ON mileage_counter.template_id = mileage_counter_templates.id
INNER JOIN coefficients
ON coefficients.mileage_counter_template_id = mileage_counter_templates.id
WHERE coefficients.engine_template_id = engine_template.id AND car_engines.id = car_engine_mileage_counters.engine_id;
This (clearly fictitious) example fails with:
ERROR: invalid reference to FROM-clause entry for table
"car_engine_mileage_counters"
LINE 7: ON mileage_counters.id = car_engine_mileage_counters...
^
HINT: There is an entry for table "measure_instances_question_instances", but it cannot be referenced
from this part of the query.
Enumerating all tables in a single FROM clause, and using WHERE AND in place of all INNER JOINs however works fine.
My question is, why? What is wrong with the inner join query? How can I fix it? Does it matter?
UPDATE cem
SET mileage = mileage_counters.mileage * coefficients.coefficient
FROM car_engine_mileage_counters cem
INNER JOIN car_engines
ON car_engines.id = cem.engine_id
INNER JOIN engine_templates
ON car_engines.template_id = engine_templates.id
INNER JOIN mileage_counters
ON mileage_counters.id = cem.mileage_counter_id
INNER JOIN mileage_counter_templates
ON mileage_counter.template_id = mileage_counter_templates.id
INNER JOIN coefficients
ON coefficients.mileage_counter_template_id = mileage_counter_templates.id
WHERE coefficients.engine_template_id = engine_template.id AND car_engines.id = cem.engine_id;