SQL DELETE Query help..joining the same table together - sql

I have a database that I need to write a delete query for.
There are thousands of participants in the database, and the table includes their internal id (first column) and then employment statuses. The table is called EE_EMPL_CAT The category ID is CAT_ID, and STAT_CD is the status of that category (employment category):
Now I need to make a delete query to delete the rows that include CAT_ID=4433 & STAT_CD ='NO'. But I only need these deleted if that same participant (=prsn_intn_id) also has CAT_ID=430 AND STAT_CD='AFACTF'. Also, to make sure all of these are current, I included an infinite end date (EFENDDT='2299-12-31').
My attempt at the code:
#UPDATE
#AQUA-435
#TOLERANCE-435
DELETE FROM &DATABASE..EE_EMPL_CAT A,
& DATABASE..EE_EMPL_CAT B
WHERE A.PRSN_INTN_ID = B.PRSN_INTN_ID
AND A.EMPL_CAT_ID = 430
AND A.EE_EMPLCAT_EFENDDT = '2299-12-31'
AND A.EMPL_STAT_CD = 'AFACTF'
AND B.EMPL_CAT_ID = 4433
AND B.EE_EMPLCAT_EFENDDT = '2299-12-31'
AND B.EMPL_STAT_CD = 'NO'

Related

SQL Server: Selecting Specific Records From a Table with Duplicate Records (Excluding Stale Data from a Query)

I'm trying to put together a query (select preferably) in SQL server that works with a single table. Said table is derived from two sets of data. Records where SET = OLD represent old data, records where SET = NEW represent new data. My intention is as follows:
If record CODE = A, keep/include the record.
If record CODE = C, keep/include the record but delete/exclude the corresponding record from the old set under the same ACT value.
If record CODE = D, delete/exclude it along with its corresponding record from the old set under the same ACT value.
If CODE = '' (blank/null), keep the record but only if it exists in the OLD set (meaning their isn't a corresponding record from the new set with the same ACT value)
What the table looks like before logic is applied:
ACT|STATUS |CODE|SET|VALUE
222| | |OLD|1
333| | |OLD|2
444| | |OLD|3
111|ADDED |A |NEW|4
222|CHANGED|C |NEW|5
333|DELETED|D |NEW|6
What the table should look like after logic is applied (end result)
ACT|STATUS |CODE|SET|VALUE
444| | |OLD|3
111|ADDED |A |NEW|4
222|CHANGED|C |NEW|5
While I can probably put together a select query to achieve the end result above I doubt it will run efficiently as the table in question has millions of records. What is the best way to do this without taking a long time to obtain the end result?
Something like this. you will have to split your query and union.
--Old Dataset
SELECT O.*
FROM MyTable O
LEFT JOIN Mytable N ON O.ACT = N.ACT AND N.[SET] = 'NEW'
WHERE O.[SET] ='OLD'
AND ISNULL(N.CODE,'A') = 'A'
UNION
-- New records
SELECT N.*
FROM MyTable N
WHERE N.[SET] ='NEW'
AND CODE <> 'D'

Find changes made in PGSQL table using SQL in Excel VBA

Is it possible to create an SQL query to compare a field within a single table to see if a change has been made and if possible list the before and after?
I have the following SQL query written in Excel 2010 VBA, which connects to an Oracle PostGreSQL database
Dim au As String
au = "SELECT id, priority, flag, code " _
& "FROM hist WHERE ( aud_dt >= '18/05/2020' AND aud_dt <='18/05/2020' ) " _
Set rs = conn.Execute(au)
With ActiveSheet.QueryTables.Add(Connection:=rs, Destination:=Range("A1"))
.Refresh
End With
Where fields include:
"priority" is the field that I'd like to check for changes which will
be a single number between 0-9
"code" is the record that has been
assigned the priority and is a mixture of numbers and letters up to 7
characters
"flag" shows a 1 as the active record, and 2 as an edited
record
"id" refers to the user account
I'd ideally like to end up with something like: id | priority | flag | priority_old | flag_old | code
Which should show the before and after changes to the priority. If the record shows priority=3 and flag=2 and code=Ab12, there must also be record with a 1 flag, as that is now the active record. If it has the same priority number for the code I'm not interested in it as that just means something else was changed instead as I have not listed all the column fields.
If the active record now shows priority=4, flag=1 and code=Ab12, that would be exactly the record I need to see.
Consider a self-join query (possibly you need to adjust date filter in WHERE depending on when items change):
SELECT h1.id, h1.priority, h1.flag,
h2.priority AS priority_old, h2.flag AS flag_old, h1.code
FROM hist h1
LEFT JOIN hist h2
ON h1.code = h2.code
AND h1.priority <> h2.priority
AND h1.flag = 1
AND h2.flag <> 1
WHERE (aud_dt >= '2020-05-18' AND aud_dt <='2020-05-18')

Selecting more than one column to query in sql

I am having a bit of trouble, probably from my understanding of SQL. Here is the SQL I am currently using:
CREATE TEMPORARY TABLE Temp
(
sPropertyCode VARCHAR(9),
sDataDate DATE,
PRIMARY KEY (sPropertyCode)
);
INSERT IGNORE Temp (sPropertyCode, sDataDate)
SELECT sPropertyCode, sDataDate
FROM tasks as t, task_data AS d
WHERE t.iTaskId = d.iTaskId
AND iRemoved = 1
AND sDataType = 'sAgencyAgreementDate'
AND iBusinessStreamId = 9;
SELECT t.sPropertyCode, sDataDate, SFirstSeen, sTaskType
FROM tasks AS t, temp AS a
WHERE iRemoved = 1
AND iBusinessStreamId = 9
AND sTaskType IN ('RF', 'IF', 'CM')
AND t.sPropertyCode = a.sPropertyCode
ORDER BY sPropertyCode, sFirstSeen;
DROP TABLE Temp;
So the references 'RF', 'IF' and 'CM' are tasks that we receive. Each propertycode can touch each of these tasks once, and only once. I would like to show the date that each one of these was touched by the propertycode. It is working at the moment but it is showing it in three columns with the tasks types in one column. I would like each task to show in a seperate column with the date it was first seen in its own corresponding column.
So from the picture below is how it is currently laid out with the code above.
And here is how I would like it to look, instead of the tasks showing down the side, I would like them to show accross in columns with their own specific dates
Thank you in advance :)
SELECT t.sPropertyCode, sDataDate, SFirstSeen, a1.sTaskType, a2.sTaskType, a3.sTaskType
FROM tasks AS t
INNER JOIN temp AS a1 on t.sPropertyCode = a1.sPropertyCode and a1.sTaskType = 'RF'
INNER JOIN temp as a2 on t.sPropertyCode = a2.sPropertyCode and a2.sTaskType = 'IF'
INNER JOIN temp as a3 on t.sPropertyCode = a3.sPropertyCode and a3.sTaskType = 'CM'
WHERE iRemoved = 1 AND iBusinessStreamId = 9
ORDER BY sPropertyCode, sFirstSeen;
You can also user outer join if not always have all 3 tast type.
What is the difference in meaning between the CM,IF and RF columns for any row in your 5-col table ? They're always the very same value in the example you listed.

Creating filter with SQL queries

I am trying to create a filter with SQL queries but am having trouble with numeric values linking to other tables.
Every time I try to link to another table, it takes the same record and repeats it for every element in the other table.
For example, here is query:
SELECT ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID AND
ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0
The last line is the actual filtering criteria.
Here is an example result:
There should only be ONE result (Item has an RID of 0). But it's repeating a copy of the one record for every result inside the substitution groups table (there's 4).
Here is my database schema for reference. The lines indicate relationships between tables and the circles indicate the values I want:
You're forgot to join between ELEMENTS and SUBSTITUTION_GROUPS in your query.
SELECT
ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM
ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE
ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID
AND ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = SUBSTITUTION_GROUPS.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0

Update 1 field in a table from another field in a different table (OS400, not a 1 to 1 relationship)

Im trying to update a field in a table from another field in a different table.
The table being updated will have multiple records that need updating from 1 match in the other table.
Example, i have a 1 million row sales history file. Those million records have aproximately 40,000 different sku codes, each row has a date and time stamp. Each sku will have multiple records in there.
I added a new field called MATCOST (material cost).
I have a second table containing SKU and the MATCOST.
So i want to stamp every line in table 1 with the corresponding SKU's MATCOST in table2. I cannot seem to achieve this when its not a 1 to 1 relationship.
This is what i have tried:
update
aulsprx3/cogtest2
set
matcost = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM )
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
But that results in the SQL error: Column qualifier or table COSKITSCOG undefined and highlighting the q in the last reference to queryfiles/coskitscog.Item
Any idea's ?
Kindest Regards
Adam
Update: This is what my tables look like in principle. 1 Table contains the sales data, the other contains the MATCOSTS for the items that were sold. I need to update the Sales Data table (COGTEST2) with the data from the COSKITCOG table. I cannot use a coalesce statement because its not a 1 to 1 relationship, most select functions i use result in the error of multiple selects. The only matching field is Item=Item99
I cant find a way of matching multiple's. In the example we would have to use 3 SQL statements and just specify the item code. But in live i have about 40,000 item codes and over a million sales data records to update. If SQL wont do it, i suppose i'd have to try write it in an RPG program but thats way beyond me for the moment.
Thanks for any help you can provide.
Ok this is the final SQL statement that worked. (there were actually 3 values to update)
UPDATE atst2f2/SAP20 ct
SET VAL520 = (SELECT cs.MATCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL620 = (SELECT cs.LABCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
VAL720 = (SELECT cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20),
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
This more compact way to do the same thing should be more efficient, eh?
UPDATE atst2f2/SAP20 ct
SET (VAL520, VAL620, VAL720) =
(SELECT cs.MATCOST, cs.LABCOST, cs.OVRCOST
FROM queryfiles/coskitscog cs
WHERE cs.ITEM = ct.pnum20)
WHERE ct.pnum20 IN (SELECT cs.ITEM
FROM queryfiles/coskitscog cs)
Qualify the columns with correlation names.
UPDATE AULSPRX3/COGTEST2 A
SET A.matcost = (SELECT matcost
FROM QUERYFILES/COSKITSCOG B
WHERE A.item99 = B.item)
WHERE EXISTS(SELECT *
FROM QUERYFILES/COSKITSCOG C
WHERE A.item99 = C.item)
From UPDATE, I'd suggest:
update
aulsprx3/cogtest2
set
(matcost) = (select Matcost from queryfiles/coskitscog where
aulsprx3/cogtest2.item99 = queryfiles/coskitscog.ITEM)
where
aulsprx3/cogtest2.item99=queryfiles/coskitscog.ITEM
Note the braces around matcost.