insert ...select ... count ... on duplicate key update error - insert-update

I created a table to hold counts of work orders by asset tag. I have 2 fields, asset_tag (which is unique) and the wo_count. I am trying to write a query that will insert/update the counts in the table. Through research on ON DUPLICATE KEY UPDATE, I have come up with this, but am getting unknown column errors.
INSERT INTO mod_workorder_counts (asset_tag, wo_count)
(SELECT t.asset_tag, count(*) AS cnt
FROM mod_workorder_data t
WHERE t.asset_tag IS NOT NULL
GROUP BY t.asset_tag)
ON DUPLICATE KEY UPDATE mod_workorder_counts.wo_count = t.cnt
When I run this I get #1054 - Unknown column 't.cnt' in 'field list'. I am not sure how to use the count values in the update.

Once you reference it as "cnt", you no longer need the "t." portion. You should reference it as just "cnt".

Related

How to upsert when using data from a sub-query (Postgres)

I have two tables:
assignments {recceptacleId, assignedCarrier}
rls_permissions {receptacleId, rlsUserId}
An assignment in this context is any receptacle to airline carrier relationship.
Whenever a new assignment comes into the assignments table, I'd like to upsert (insert if new row or update if it's an existing receptacle being assigned to a new airline carrier) my rls_permissions table.
The issue I'm having with upsert, specifically ON CONFLICT ON CONSTRAINT, is that my insert statement contains a sub-query for the data to be inserted and therefore I'm not sure how to write the DO UPDATE SET part of the statement
I've tried using 'excluded' to try and single out the assignedCarrier that I want to update based on the previous conflict however I keep receiving "ERROR: column excluded.receptacleId does not exist"
My pkey looks like this:
CREATE UNIQUE INDEX rls_permissions_pkey ON rls_permissions("receptacleId" text_ops);
Dummy data could be:
receptacleID assignedCarrier
aaaaaaaaaa00 AA
Where AA is "American Airlines"
INSERT INTO rls_permissions ("receptacleId","rlsUserId")
SELECT DISTINCT assignments."receptacleId", assignments."assignedCarrier"
FROM assignments
ON CONFLICT ON CONSTRAINT rls_permissions_pkey
DO UPDATE SET "rlsUserId" = (SELECT DISTINCT assignments."assignedCarrier"
FROM assignments
WHERE assignments."receptacleId" = excluded."receptacleId");
The excepted result is that if no conflict, the data returned from the sub-query is inserted into a new row on the permissions table.
If there is a conflict, I'd like to update ONLY the newly assigned carrier, and not update or insert a new line since that receptacle already exists.
You don't need a subquery in the UPDATE part. You can access the values for the INSERT part through the excluded keyword.
INSERT INTO rls_permissions ("receptacleId","rlsUserId")
SELECT DISTINCT assignments."receptacleId", assignments."assignedCarrier"
FROM assignments
ON CONFLICT ON CONSTRAINT rls_permissions_pkey
DO UPDATE SET "rlsUserId" = excluded."rlsUserId";
the reference to excluded."rlsUserId" refers to the value that would have been inserted into the column rlsUserId and thus it's the value retrieved through assignments."assignedCarrier" from your SELECT statement.

SQL/DB2 SQLSTATE=23505 error when executing an UPDATE statement

I am getting a SQLSTATE=23505 error when I execute the following DB2 statement:
update SEOURLKEYWORD
set URLKEYWORD = REPLACE(URLKEYWORD, '/', '-')
where STOREENT_ID = 10701
and URLKEYWORD like '%/%';
After a quick search, a SQL state 23505 error is defined as follows:
AN INSERTED OR UPDATED VALUE IS INVALID BECAUSE THE INDEX IN INDEX SPACE CONSTRAINS COLUMNS OF THE TABLE SO NO TWO ROWS CAN CONTAIN DUPLICATE VALUES IN THOSE COLUMNS RID OF EXISTING ROW IS X
The full error I am seeing is:
The full error I am seeing is:
DB2 Database Error: ERROR [23505] [IBM][DB2/LINUXX8664] SQL0803N One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "2" constrains table "WSCOMUSR.SEOURLKEYWORD" from having duplicate values for the index key. SQLSTATE=23505
1 0
I'm not sure what the "index identified by '2'" means, but it could be significant.
The properties of the columns for the SEOURLKEYWORD table are as follows:
Based on my understanding of this information, the only column that is forced to be unique is SEOURLKEYWORD_ID, the primary key column. This makes it sound like the update statement I'm trying to run is attempting to insert a row that has a SEOURLKEYWORD_ID that already exists in the table.
If I run a select * statement on the rows I'm trying to update, here's what I get:
select * from SEOURLKEYWORD
where storeent_id = 10701
and lower(URLKEYWORD) like '%/%';
I don't understand how executing the UPDATE statement is resulting in an error here. There are only 4 rows this statement should even be looking at, and I'm not manually updating the primary key at all. It kind of seems like it's reinserting a duplicate row with the updated column value before deleting the existing row.
Why am I seeing this error when I try to update the URLKEYWORD column of these four rows? How can I resolve this issue?
IMPORTANT: As I wrote this question, I have narrowed down the problem to the last of the four rows in the table above, SEOURLKEYWORD_ID = 3074457345616973668. I can update the other three rows just fine, but the 4th row is causing the error, I have no idea why. If I run a select * from SEOURLKEYWORD where SEOURLKEYWORD_ID = 3074457345616973668;, I see only the 1 row.
The error is pretty clear. You have a unique index/constraint in the table. Say you have two rows like this:
STOREENT_ID
URLKEYWORD
10701
A/B
10701
A-B
When the first version is replaced by 'A-B', the result would violate a unique constraint on (STOREENT_ID, URLKEYWORD) or (URLKEYWORD) (do note that other columns could possibly be included in the unique constraint/index as well).
You could avoid these situations by not updating them. I don't know what columns the unique constraint is on, but let's say only on URLKEYWORD. Then:
update SEOURLKEYWORD
set URLKEYWORD = REPLACE(URLKEYWORD, '/', '-')
where STOREENT_ID = 10701 and
URLKEYWORD like '%/%' and
not exists (select 1 from SEOURLKEYWORD s2 where replace(s2.urlkeyword, '/', '-') = REPLACE(SEOURLKEYWORD.URLKEYWORD, '/', '-')
);
Note the replace() is required for both columns because you might have:
A-B/C
A/B-C
These only conflict after the replacement in both values.
To complement the answer given by #GordonLinoff, here is a query that can be used to find a table's unique constraints, with their IDs, and the columns included in them:
SELECT c.tabschema, c.tabname, i.iid AS index_id, i.indname, ck.colname
FROM syscat.tabconst c
INNER JOIN syscat.indexes i
ON i.indname = c.constname -- unique index name matches constraint name
AND i.tabschema = c.tabschema AND i.tabname = c.tabname
INNER JOIN syscat.keycoluse ck
ON ck.constname = c.constname
AND ck.tabschema = c.tabschema c.tabname = ck.tabname AND
WHERE c.type = 'U' -- constraint type: unique
AND (c.tabschema, c.tabname) = ('YOURSCHEMA', 'YOURTABLE') -- replace schema/table
ORDER BY i.iid, ck.colseq

Insert row to database based on form values not currently in database

I am using Access 2013 and I am trying to insert rows to a table but I don't want any duplicates. Basically if not exists in table enter the data to table. I have tried to using 'Not Exists' and 'Not in' and currently it still does not insert to table. Here is my code if I remove the where condition then it inserts to table but If I enter same record it duplicates. Here is my code:
INSERT INTO [UB-04s] ( consumer_id, prov_id, total_charges, [non-covered_chrgs], patient_name )
VALUES ([Forms]![frmHospitalEOR]![client_ID], [Forms]![frmHospitalEOR]![ID], Forms![frmHospitalEOR].[frmItemizedStmtTotals].Form.[TOTAL BILLED], Forms![frmHospitalEOR].[frmItemizedStmtTotals].Form.[TOTAL BILLED], [Forms]![frmHospitalEOR]![patient_name])
WHERE [Forms]![frmHospitalEOR]![ID]
NOT IN (SELECT DISTINCT prov_id FROM [UB-04s]);
You cannot use WHERE in this kind of SQL:
INSERT INTO tablename (fieldname) VALUES ('value');
You can add a constraint to the database, like a unique index, then the insert will fail with an error message. It is possible to have multiple NULL values for several rows, the unique index makes sure that rows with values are unique.
To avoid these kind of error messages you can build a procedure or use code to check data first, and then perform some action - like do the insert or cancel.
This select could be used to check data:
SELECT COUNT(*) FROM [UB-04s] WHERE prov_id = [Forms]![frmHospitalEOR]![ID]
It will return number of rows with the spesific value, if it is 0 then you are redy to run the insert.

Duplicate key error with PostgreSQL INSERT with subquery

There are some similar questions on StackOverflow, but they don't seem to exactly match my case. I am trying to bulk insert into a PostgreSQL table with composite unique constraints. I created a temporary table (temptable) without any constraints, and loaded the data (with possible some duplicate values) in it. So far, so good.
Now, I am trying to transfer the data to the actual table (realtable) with unique index. For this, I used an INSERT statement with a subquery:
INSERT INTO realtable
SELECT * FROM temptable WHERE NOT EXISTS (
SELECT 1 FROM realtable WHERE temptable.added_date = realtable.added_date
AND temptable.product_name = realtable.product_name
);
However, I am getting duplicate key errors:
ERROR: duplicate key value violates unique constraint "realtable_added_date_product_name_key"
SQL state: 23505
Detail: Key (added_date, product_name)=(20000103, TEST) already exists.
My question is, shouldn't the WHERE NOT EXISTS clause prevent this from happening? How can I fix it?
The NOT EXISTS clause only prevents rows from temptable conflicting with existing rows from realtable; it will not prevent multiple rows from temptable from conflicting with each other. This is because the SELECT is calculated once based on the initial state of realtable, not re-calculated after each row is inserted.
One solution would be to use a GROUP BY or DISTINCT ON in the SELECT query, to omit duplicates, e.g.
INSERT INTO realtable
SELECT DISTINCT ON (added_date, product_name) *
FROM temptable WHERE NOT EXISTS (
SELECT 1 FROM realtable WHERE temptable.added_date = realtable.added_date
AND temptable.product_name = realtable.product_name
)
ORDER BY ???; -- this ORDER BY will determine which of a set of duplicates is kept by the DISTINCT ON

Insert statement with no joins results in duplicates where no duplicates existed previously?

I am having an issue with some SQL that is resulting in results that I wouldn't expect. I am storing information from a variety of tables in another table which is used as part of a search page on a website. All of the page data for each page, along with data from other elements on other pages (like calendars, etc) is referenced in a table called pageContentCache. This table has normally has an index against created with the following:
alter table pageContentCache add
constraint [IX_pageContentCache] PRIMARY KEY CLUSTERED (
[objectId]
)
For some reason that to me would appear to be a duplicate objectId, an issue has started occurring with one instance of this software, resulting in the following error:
Msg 1505, Level 16, State 1 Procedure sp_rebuildPageContentCache, Line 50
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.pageContentCache' and the index name 'IX_pageContentCache'. The duplicate key value is (21912).
So, to debug the issue, I had got the procedure to load all of the data it was going to input into the pageContentCache table into a temporary table, #contentcache, first, so I could have a look through it.
This is where I'm starting to get a little confused...
Once the data has been inserted into #contentcache (which has two columns, objectId and content), I can run the following SQL statement and it will return nothing:
select objectId, count(objectId) from #contentcache
group by objectId having count(objectId) > 1
This returns no records. If I then run the following SQL:
insert into pageContentCache (objectId, contentData)
select objectId, content
from #contentcache
This inserts all of the data from #contentcache into pageContentCache as you'd expect. However, if I then run the following SQL, it returns duplicates:
select objectId, count(objectId) from pageContentCache
group by objectId having count(objectId) > 1
This then returns duplicates:
objectId (no column name)
21912 2
There are no triggers or anything like that associated with this table and the insert statement is merely copying the data from one table to another, so... where is this duplicate coming from?
Try the following:
insert into pageContentCache (objectId, contentData)
select distinct objectId, content
from #contentcache
Can't see why you would have duplicates since, as you mentioned, there are no joins in your select statement. Anyways, my guess is that the distinct keyword will ensure that the duplicates are eliminated.
This is a SQL Server database error I have seen before. You may want to patch the latest service pack and retry.
I am not so sure that this statement does what you think it does:
select objectId, count(objectId) from #contentcache
group by objectId having count(objectId) > 1
Can you try this instead:
WITH SUBQUERY AS
( select
COUNT(objectId) OVER (PARTITION BY objectId) AS CNT_OBJECT_IDS,
objectId
FROM #contentcache)
SELECT * FROM SUBQUERY WHERE CNT_OBJECT_IDS > 1
See if this gets you any rows back.
Also, I've never worked with clusters before and I am wondering if they do some additional things that we are not aware of. Can you try just saying
PRIMARY KEY
instead of
PRIMARY KEY CLUSTERED
in your constraint definition and see if that affects your problem at all?