Why am I getting the error: "Ambiguous column" in my query? - sql

In this query I inserting records into a new empty table I created. These records are derived from another table where I am left joining that table to itself, in order to output records that are not included in the recent table that is appended on top of an older table. So basically it outputs records that were deleted.
CREATE DEFINER=`definer` PROCEDURE `stored_procedure_name`()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
START TRANSACTION;
INSERT INTO exceptions_table (
`insert_date`,
`updated`,
`account_number`,
`id_number`)
SELECT
`insert_date`,
`updated`,
`account_number`,
`id_number`
FROM original_table ot1
LEFT JOIN original_table ot2
ON ot1.`account_number` = vdcaas2.`account_number`
AND ot2.`insert_date` = '2022-12-20'
WHERE ot1.`insert_date` = '2022-12-10'
AND ot2.`account_number` IS NULL;
COMMIT;
END
I get an error stating: "SQL Error: Column "insert_date" in field list is ambiguous.
I'm not sure why because I have specified which table I am grabbing "insert_date" from when INSERTING and when SELECTING and JOINING..

Every row in your query has two columns called insert_date: one from the table you've aliased as "ot1", and one from the table (as it happens, the same table) you've aliased as "ot2".
The database system doesn't know which one you want, so you have to tell it by writing either "ot1.insert_date" or "ot2.insert_date", just as you do elsewhere in the query:
... ot2.`insert_date` = '2022-12-20'
...
... ot1.`insert_date` = '2022-12-10'
The same is true of the other columns you've listed to select.

You need to change this
SELECT
`insert_date`,
`updated`,
`account_number`,
`id_number`
to this
SELECT
ot1.`insert_date`,
ot1.`updated`,
ot1.`account_number`,
ot1.`id_number`
or this
SELECT
ot2.`insert_date`,
ot2.`updated`,
ot2.`account_number`,
ot2.`id_number`
or some combination

Issue
SQL Error: Column "insert_date" in field list is ambiguous error means that the query is trying to reference the "insert_date" column from both tables, ot1 and ot2.
Try the following:
SELECT
ot1.`insert_date`,
ot1.`updated`,
ot1.`account_number`,
ot1.`id_number`
Also, you have a typo in your query:
ON ot1.`account_number` = vdcaas2.`account_number` -> ON ot1.`account_number` = ot2.`account_number`

Related

How to UPDATE table using calculated column from subquery in Sybase

I have a table that I want to update that contains a column called 'expiration_days'. What I am doing is trying to update the records in the 'expiration_days' column by using an 'alias column' (not sure what to call it) that is apart of a subquery where I calculated the number of days until a user's password has expired. The column from the subquery that I want to take the values from and update them in the actual table is called 'countdown'. I named the subquery results 'query' (derived table). So far I have this:
UPDATE LOGIN_INFO
SET expiration_days = query.countdown
FROM (
select li.name as name, countdown = 365 - datediff(day, sl.pwdate, getdate())
from master..syslogins sl, LOGIN_INFO li
where li.name = sl.name) query
WHERE LOGIN_INFO.name = query.name
The issue I am having is I get this error: You cannot use a derived table in the FROM clause of an UPDATE or DELETE statement. ( I also get: Incorrect syntax near ')' on the subquery where clause)
Is there a way I can take the results from the calculated column in a select statement and update the column in the LOGIN_INFO table in one query or some other easy clean way?
Perhaps something along the lines of:
update login_info
set expiration_days = (select 365 - datediff(day,s1.pwdate,getdate())
from master..syslogins s1
where s1.name = li.name)
from login_info li
where exists(select 1
from master..syslogins s2
where s2.name = li.name)
NOTES:
the exists() clause is added to insure we don't erroneously update a row in login_info that doesn't have a match in syslogins, otherwise OP will need to modify the logic accordingly (ie, what to set expiration_days to if a matching rows does not exist in syslogins?)
if syslogins.pwdate is NULLable (I don't have access to a running ASE instance at the moment) then OP will need additional logic to handle the scenario where s1.pwdate is NULL; default countdown to some hardcoded value? or perhaps modify the exists() to include the additional clause and s2.pwdate is not NULL?

Using a JOIN within a UNION ALL view creation

I am creating a view merging two tables with some similar fields and some dissimilar fields. I have this 95% working but there is one field from table A that matches up with a field from table B but only if you use that field from B as a join to pull a field from table C. The only part of the code below that isn't working is the JOIN. I could just put both of the fields in and do the logic to get provider_id from the ehruser_id in the model, but I feel like it should be doable in the SQL and I just don't have the knowledge to get that last bit working yet
DROP VIEW IF EXISTS vunifiedschedule CASCADE;
CREATE VIEW vunifiedschedule AS
SELECT
schedule_block.id as vid,
schedule_block.reason as vblock_reason,
NULL as vappointment_reason_id,
schedule_block.when_ts as vwhen,
schedule_block.deleted_ts as vdeleted_when,
schedule_block.placeofservice_id as vlocation_id,
schedule_block.duration as vduration,
true as vappointment_book,
schedule_block.note as vnote
FROM schedule_block
LEFT JOIN ( SELECT id FROM provider) as vprovider_id ON provider.ehruser_id = schedule_block.ehruser_id
UNION ALL
SELECT
appointment.id AS vid,
NULL as vblock_reason,
appointment.appointmentreason_id AS vappointment_reason_id,
appointment.appt_when AS vwhen,
appointment.deleted_when AS vdeleted_when,
appointment.location_id AS vlocation_id,
appointment.visit_length AS vduration,
appointment.appointment_book as vappointment_book,
appointment.note AS vnote,
appointment.provider_id as vprovider_id
FROM appointment
The error I get is
ERROR: missing FROM-clause entry for table "provider"
LINE 14: ...ELECT id FROM provider) as vprovider_id ON provider.e...
The error is pretty clear. You have no provider. I think you intend:
FROM schedule_block LEFT JOIN
( SELECT id FROM provider) vprovider_id
ON vprovider.ehruser_id = schedule_block.ehruser_id
--------^
However the subquery is unnecessary:
FROM schedule_block LEFT JOIN
provider
ON provider.ehruser_id = schedule_block.ehruser_id
1st select stmt of view has 9 columns but 2nd select stmt has 10 columns. This view will error with message "Query block has incorrect number of result columns
You selected 9 columns from the first table and 10 from the second, when using union you must have the same number of columns in both queries and the type columns selected must match.

ORA-01779 cannot modify a column which maps to a non key-preserved table

I have a following SELECT query -
SELECT C.CASE_TITL_NM,RA.V_CUST_NUMBER
FROM KDD_CASES C
JOIN FCT_RA RA
ON RA.N_RA_ID = C.RA_ID
WHERE UPPER(C.CNTRY_KEY_ID) LIKE '%MANUAL%'
AND C.SCORE_CT IN (99,100)
AND C.STATUS_CD = 'CCD'
AND C.CASE_TITL_NM NOT LIKE 'MANUAL%'
I need to update value in col V_CUST_NUMBER with value in col CASE_TITL_NM so I plugged my SELECT inside following UPDATEstatement and ran it only to get ORA01779 -
UPDATE (
SELECT C.CASE_TITL_NM,RA.V_CUST_NUMBER
FROM KDD_CASES C
JOIN FCT_RA RA
ON RA.N_RA_ID = C.RA_ID
WHERE UPPER(C.CNTRY_KEY_ID) LIKE '%MANUAL%'
AND C.SCORE_CT IN (99,100)
AND C.STATUS_CD = 'CCD'
AND C.CASE_TITL_NM NOT LIKE 'MANUAL%'
) X
SET X.V_CUST_NUMBER = X.CASE_TITL_NM;
SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 - "cannot modify a column which maps to a non key-preserved table"
*Cause: An attempt was made to insert or update columns of a join view which
map to a non-key-preserved table.
*Action: Modify the underlying base tables directly.
Can anybody explain what does this error mean and what would be the right UPDATE query?
What it means is the query as specified results in an output set that has duplicated rows for RA. Seeing as one RA row maps to two different C rows you cannnot update RA, because there is the potential to try and update the sole RA row to have two different values
You can try using a MERGE statement, using SQL-that-writes-SQL to create a bunch of UPDATE statements, or modifying the join condition so duplicate rows from RA are not present in the output and the primary key from RA is covered
I was able to run my query it by using EXIST clause
UPDATE FCT_RA F
SET F.V_CUST_NUMBER = ( SELECT CASE_TITL_NM
FROM KDD_CASES C
WHERE F.N_RA_ID = C.RA_ID
AND UPPER(CNTRY_KEY_ID) LIKE '%MANUAL%'
AND SCORE_CT IN (99,100)
AND STATUS_CD = 'CCD'
AND CASE_TITL_NM NOT LIKE 'MANUAL%')
WHERE EXISTS ( SELECT 1
FROM KDD_CASES C
WHERE F.N_RA_ID = C.RA_ID
AND UPPER(CNTRY_KEY_ID) LIKE '%MANUAL%'
AND SCORE_CT IN (99,100)
AND STATUS_CD = 'CCD'
AND CASE_TITL_NM NOT LIKE 'MANUAL%');
Please look here, especially about key preserved
The updatable view query must unambiguously return each row of the
modified table only one time. The query must be “key preserved”, which
means Oracle must be able to use a primary key or unique constraint to
ensure that each row is only modified once.

Updating a table row multiple values oracle 11g

I m struggling to update one column for a table with a sub query. I have a table where currently one of the values is null.
Currently I have:
UPDATE DW1_PURCHASES SET DW1_PURCHASES.TOTAL_AMT =
(
SELECT DW1_PURCHASES.QUANTITY * DW1_PRODUCTS.PRICE
FROM DW1_PURCHASES, DW1_PRODUCTS
WHERE DW1_PURCHASES.PRODUCT_ID = DW1_PRODUCTS.PRODUCT_ID
)
Although subquery returns data which I need to insert I get a error of single row subquery returns multiple rows.How do I basically shift subquery result to the table?
Thanks.
You don't have to JOINthe update table inside the sub-query. Just correlate the sub-query with update table
UPDATE DW1_PURCHASES
SET DW1_PURCHASES.TOTAL_AMT =
(
SELECT DW1_PURCHASES.QUANTITY * DW1_PRODUCTS.PRICE
FROM DW1_PRODUCTS
WHERE DW1_PURCHASES.PRODUCT_ID = DW1_PRODUCTS.PRODUCT_ID
)
Note : If your DW1_PRODUCTS table has duplicated PRODUCT_ID then even now there is a possibility to get the same error

sql server to delete a record and add sum of value on trigger

I have two tables in my database, bill_datail and bill_log. I want to delete one record from table bill_log and after that trigger an action to do something in table bill_detail. My code for delete is the following:
DELETE FROM [mydatabase].[dbo].[Bill_Log]
WHERE [mydatabase].[dbo].[Bill_Log].[CU_BILL_ID] in
(SELECT
FROM [mydatabase].[dbo].[Bill_Log],[mydatabase].[dbo].[Bill_Detail]
where [mydatabase].[dbo].[Bill_Log].bill_id=37
and [mydatabase].[dbo].[Bill_Log].bill_id=[mydatabase].[dbo].[CU_Bill_Detail].cu_bill_id
and [mydatabase].[dbo].[Bill_Detail].Pay_date>20130206
and [CL_Com_Rec_Description] like '%اoffpage%'
and [mydatabase].[dbo].[Bill_Log].amount<0
and [mydatabase].[dbo].[Bill_Log].[Com_Act_Date]='2013/02/07')
go
CREATE TRIGGER [mydatabase].[dbo].[Bill_Log]
ON [mydatabase].[dbo].[Bill_Log]]
AFTER Delete
AS
---
BEGIN
-- get 'amount' from deleted record and sum it to field 'amount' of bill detail
END
But in delete action I get the following error:
'Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
And I don't know how to fix the error and do the second part.
You only need to get a list of CU_BILL_ID to search. So remove all other fields from inner query and just select CU_BILL_ID.
DELETE FROM [mydatabase].[dbo].[CU_Bill_Log]
WHERE [mydatabase].[dbo].[CU_Bill_Log].[CU_BILL_ID] in
(SELECT cu_bill_id
FROM [mydatabase].[dbo].[CU_Bill_Detail]
where Pay_date>13930206)
and [mydatabase].[dbo].[CU_Bill_Log].cu_bill_id=37
and [mydatabase].[dbo].[CU_Bill_Log].cu_bill_id=
and [mydatabase].[dbo].[CU_Bill_Detail].
and [CL_Com_Rec_Description] like '%اoffpage%'
and [mydatabase].[dbo].[CU_Bill_Log].amount<0
and [mydatabase].[dbo].[CU_Bill_Log].[CL_Com_Act_Date]='2013/02/07'
go
Try this please.
if you want use of "in" keyword in your main query ,
the subquery must return just one column as result
Select ID,F_Name,L_Name
From Clients
Where ID in(
Select ClientID
From Orders
Where OrderNo > 120
)