What is difference between 2 sql queries? - sql

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.

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.

multi-inner join statement

I'm currently trying to draw multiple tables through several inner-join statements. However, I am continually hit with the following error:
ORA-00904: "PART"."ITEM_CLASS": invalid identifier
I've visited several other pages here but that problem did not coincide with mine.
Here is the SQL query:
SELECT Slsrep_Number, AVG(Commission_Rate) AS AVG_Rate, MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';
Here are the tables being used (screenshots):
The pictures are listed in the order that I am referencing them in the SQL query.
You need to reference the tables in the FROM clause. You can't just reference them.
You should also use table aliases and proper, explicit, standard JOIN syntax.
So:
SELECT sr.Slsrep_Number,
AVG(?.Commission_Rate) AS AVG_Rate,
MAX(?Total_Commission) as MAX_Comission
FROM Sales_Rep sr JOIN
Customer c
ON sr.Slsrep_Number = c.Slrsrep_Number JOIN
Orders o
ON c.C_Number = o.C_Number JOIN
Order_Line ol
ON o.Order_Number = ol.Order_Number
Part p
ON ol.Part_Number = p.Part_Number
WHERE p.Item_Class = 'SG';
The ? is for the alias for the column with the commission.
The query now "looks" right. However, I don't think it is particularly useful. If that is the case, ask another question and provide sample data, desired results, and an explanation of what you want to accomplish.
Customer,Orders,Order_Line and Part Tables are missing in the from clause.Try This.
SELECT Slsrep_Number,
AVG(Commission_Rate) AS AVG_Rate,
MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep,Customer,Orders,Order_Line,Part
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';

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])

POSTGRES Group by / Inner Join

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;

Ignore null values in select statement

I'm trying to retrieve a list of components via my computer_system, BUT if a computer system's graphics card is set to null (I.e. It has an onboard), the row isn't returned by my select statement.
I've been trying to use COALESCE without results. I've also tried with and OR in my WHERE clause, which then just returns my computer system with all different kinds of graphic cards.
Relevant code:
SELECT
computer_system.cs_id,
computer_system.cs_name,
motherboard.name,
motherboard.price,
cpu.name,
cpu.price,
gfx.name,
gfx.price
FROM
public.computer_case ,
public.computer_system,
public.cpu,
public.gfx,
public.motherboard,
public.ram
WHERE
computer_system.cs_ram = ram.ram_id AND
computer_system.cs_cpu = cpu.cpu_id AND
computer_system.cs_mb = motherboard.mb_id AND
computer_system.cs_case = computer_case.case_id AND
computer_system.cs_gfx = gfx.gfx_id; <-- ( OR computer_system.cs_gfx IS NULL)
Returns:
1;"Computer1";"Fractal Design"; 721.00; "MSI Z87"; 982.00; "Core i7 I7-4770K "; 2147.00; "Crucial Gamer"; 1253.00; "ASUS GTX780";3328.00
Should I use Joins? Is there no easy way to say return the requested row, even if there's a bloody NULL value. Been struggling with this for at least 2 hours.
Tables will be posted if needed.
EDIT: It should return a second row:
2;"Computer2";"Fractal Design"; 721.00; "MSI Z87"; 982.00; "Core i7 I7-4770K "; 2147.00; "Crucial Gamer"; 1253.00; "null/nothing";null/nothing
You want a LEFT OUTER JOIN.
First, clean up your code so you use ANSI joins so it's readable:
SELECT
computer_system.cs_id,
computer_system.cs_name,
motherboard.name,
motherboard.price,
cpu.name,
cpu.price,
gfx.name,
gfx.price
FROM
public.computer_system
INNER JOIN public.computer_case ON computer_system.cs_case = computer_case.case_id
INNER JOIN public.cpu ON computer_system.cs_cpu = cpu.cpu_id
INNER JOIN public.gfx ON computer_system.cs_gfx = gfx.gfx_id
INNER JOIN public.motherboard ON computer_system.cs_mb = motherboard.mb_id
INNER JOIN public.ram ON computer_system.cs_ram = ram.ram_id;
Then change the INNER JOIN on public.gfx to a LEFT OUTER JOIN:
LEFT OUTER JOIN public.gfx ON computer_system.cs_gfx = gfx.gfx_id
See PostgreSQL tutorial - joins.
I very strongly recommend reading an introductory tutorial to SQL - at least the PostgreSQL tutorial, preferably some more material as well.
It looks like it's just a bracket placement issue. Pull the null check and the graphics card id comparison into a clause by itself.
...
computer_system.cs_case = computer_case.case_id AND
(computer_system.cs_gfx IS NULL OR computer_system.cs_gfx = gfx.gfx_id)
Additionally, you ask if you should use joins. You are in fact using joins, by virtue of having multiple tables in your FROM clause and specifying the join criteria in the WHERE clause. Changing this to use the JOIN ON syntax might be a little easier to read:
FROM sometable A
JOIN someothertable B
ON A.somefield = B.somefield
JOIN somethirdtable C
ON A.somefield = C.somefield
etc
Edit:
You also likely want to make the join where you expect the null value to be a left outer join:
SELECT * FROM
first_table a
LEFT OUTER JOIN second_table b
ON a.someValue = b.someValue
If there is no match in the join, the row from the left side will still be returned.