Delete rows present in other table - sql

I have two tables A and B containing many columns, two of which in use are SKU and Typedesc.
I created a table C by joining A and B on sku and typedesc
create table C as
select A.*
from A inner join
B
on A.sku=B.sku and trim(A.typedesc)=trim(B.typedesc)
C has approx. 130,000 records
Now I want to delete the rows in A which are present in C
delete from A A1
where exists (select 1
from C c1
where A1.sku=c1.sku and trim(A1.typedesc)=trim(c1.typedesc)
)
It says 145,000 rows deleted.
Where did the extra 15,000 rows came from? Is there something wrong with my delete query? So when I join two tables, C should also have 145,000 but instead it has only 130,000!! why is this so? A or B does not contain any primary key.
Even if i delete B from A directly, the number of rows deleted remains 145,000.
delete from A A1
where exists (select 1
from B b1
where A1.sku=b1.sku and trim(A1.typedesc)=trim(b1.typedesc)
)

The EXISTS looks alright, but without seeing which rows are being deleted it's hard to tell what the problem is, and I don't want to review 145,000 rows any more than you do :)
Try this alternative and see if it makes any difference:
DELETE FROM A
WHERE (SKU, TRIM(TypeDesc)) IN (SELECT SKU, TRIM(TypeDesc) FROM B)

Related

Select rows from table where a certain value in a joined table does not exist

I have two tables, playgrounds and maintenance, which are linked with a foreign key. Whenever there is a maintenance on a playground, it will be saved in the table and connected to the respective playground.
Table A (playgrounds):
playground_number
Table B (maintenance):
playground_number (foreign key),
maintenance_type (3 different types),
date
What I now want is to retrieve all the playgrounds on which a certain type of maintenance has NOT been performed yet IN a certain year. For instance all playgrounds that do not have a maintenance_type = 1 in the year 2022 connected yet, although there could be multiple other maintenance_types because they are more frequent.
This is what I have tried (pseudo):
SELECT DISTINCT A.playground_number
FROM table A
JOIN table B ON A.playground_number = B.playground_number (FK)
WHERE NOT EXISTS (SELECT B.maintenance_type FROM table B
WHERE B.maintenance_type = 1 AND year(B.date) = 2022
However this will return nothing as soon as there is only one entry with maintenance_type 1 within the table.
I am struggling with this query for a while, so would appreciate some thoughts :) Many thanks.
You need to correlate the exists subquery to the outer B table. Also, you don't even need the join.
SELECT DISTINCT a.playground_number
FROM table_a a
WHERE NOT EXISTS (
SELECT 1
FROM table_b b
WHERE b.playground_number = a.playground_number AND
b.maintenance_type = 1 AND
YEAR(b.date) = 2022
);
Please consider this. I don't think you need JOIN.
SELECT DISTINCT A.playground_number
FROM table A
WHERE A.playground_number NOT IN (SELECT B.playground_number FROM table B
WHERE B.maintenance_type = 1 AND year(B.date) = 2022)
Please let me know if I understand it incorrectly.

Update based of 1st and 2nd table

I have 3 tables.
1st table – MainTable - tableA
Have Project Name and description
A Apple
B Banana
C Carrot
2nd table - Table B
Child table :
A.10
A.20
A.30
B.10
B.20
B.30
Name of project (A, B, C) is Foreign key to table Child.
I have to update third table (table C) based on the
A …Apple
B…Banana
C…Carrot
This is Working fine with inner join.
Now when I am doing updates on code 10, 20 and 30 .. with ref to A, B and C of 10,20 and 30
It is not working.
Here is the query I wrote which is working fine to Update A, B and C
UPDATE C
SET c.[ProjectName] = a.[sysprojectname]
FROM TableC C
inner join tableA a ON c.[CostOBJProject]=a.[workpackageid]
Where c.[ProjectName] is null or c.[ProjectName]=''
So question is – I have to update table C based on value of table B with foreign key to table A.
in case I have value A and 10 in the tableC , then it should update the description in tableC .
Please check this link, this will help you
https://dev.mysql.com/doc/refman/5.7/en/update.html
I think you have problem on your syntax.
You can perform connected tables inside the UPDATE query.
UPDATE TableC, tableA
SET TableC.[ProjectName] = tableA.[sysprojectname]
Where tableA.connectcolumn = TableC.connectcolumn
AND (TableC.[ProjectName] is null or TableC.[ProjectName]='' )
With update syntax it has to be strict, therefore LEFT JOIN is not allowed on this scenario. It is equivalent to EQUI JOIN, an old style of joining.
SET clause commands the interpreter to manipulate only that column, even tho both columns were called.
With the complexity of your code you added OR logic command, would be nice to add parenthesis to properly utilize the logic.

Delete records from 2 tables with 1 query

I need to delete records from 2 different tables that are linked via job#
One table contains dates for completion and I need to delete all records that were completed between 1999 and 2001. In the second table I need to delete all phases of the job where Job number from table 1 match job number in table 2
I've researched a bit and came up with something like this but when running it I receive "Too Many Fields Selected"
DELETE a.,b.
FROM PUB_jc_job a
LEFT JOIN PUB_jc_phase b
ON b.jph_job = a.job_num
WHERE PUB_jc_job.job_compdate BETWEEN #3/31/1999# AND #12/31/2001#
Please remove dot(.) from table alias "a., b." and retry.
DELETE a, b FROM PUB_jc_job a INNER JOIN PUB_jc_phase b ON b.jph_job = a.job_num WHERE PUB_jc_job.job_compdate BETWEEN #3/31/1999# AND #12/31/2001#

For MS Access SQL, want to use EXCEPT in Access for three columns in table1 to 1 column in table 2

I have 3 columns in table A. I am trying to design a query that will call out all the values (in the three columns) that do not apepar in the 1 column I have in table B. If it helps to make it more clear, table B is a list of currencies in ISO codes and table A is three columns of currencies being used, I am identifying all those values that are NOT using ISO codes to denote their currency.
Currently, I can't seem to get them all to match to the one column, so I made 2 more columns in table B so I can match them individually. My constraints are, I cannot change table A and I must do this in one query. What I got so far is below.
SELECT m.Currency1, i.ISO_Code, m.Currency2 , i.ISO_Code1, m.Currency3, i.ISO_Code2
FROM A AS m
LEFT JOIN B AS i
ON m.Currency=i.ISO_Code
AND m.Currency2=i.ISO_Code1
AND m.Currency3=i.ISO_Code2
WHERE i.ISO_Code is NULL
OR i.ISO_Code1 is NULL
OR i.ISO_Code2 is NULL;
I wouldn't bother making multiple columns in 'B'. I played with this in SQLFiddle and got it to work.
Something like this:
SELECT
m.Currency1, i.ISO_Code,
m.Currency2, j.ISO_Code AS ISO_Code1,
m.Currency3, k.ISO_Code AS ISO_Code2
FROM A AS m
LEFT JOIN B as i
ON m.Currency1 = i.ISO_Code
LEFT JOIN B as j
ON m.Currency2 = j.ISO_Code
LEFT JOIN B as k
ON m.Currency3 = k.ISO_Code
WHERE
i.ISO_Code IS NULL OR
j.ISO_Code IS NULL OR
k.ISO_Code IS NULL

SQL Query - Ensure a row exists for each value in ()

Currently struggling with finding a way to validate 2 tables (efficiently lots of rows for Table A)
I have two tables
Table A
ID
A
B
C
Table matched
ID Number
A 1
A 2
A 9
B 1
B 9
C 2
I am trying to write a SQL Server query that basically checks to make sure for every value in Table A there exists a row for a variable set of values ( 1, 2,9)
The example above is incorrect because t should have for every record in A a corresponding record in Table matched for each value (1,2,9). The end goal is:
Table matched
ID Number
A 1
A 2
A 9
B 1
B 2
B 9
C 1
C 2
C 9
I know its confusing, but in general for every X in ( some set ) there should be a corresponding record in Table matched. I have obviously simplified things.
Please let me know if you all need clarification.
Use:
SELECT a.id
FROM TABLE_A a
JOIN TABLE_B b ON b.id = a.id
WHERE b.number IN (1, 2, 9)
GROUP BY a.id
HAVING COUNT(DISTINCT b.number) = 3
The DISTINCT in the COUNT ensures that duplicates (IE: A having two records in TABLE_B with the value "2") from being falsely considered a correct record. It can be omitted if the number column either has a unique or primary key constraint on it.
The HAVING COUNT(...) must equal the number of values provided in the IN clause.
Create a temp table of values you want. You can do this dynamically if the values 1, 2 and 9 are in some table you can query from.
Then, SELECT FROM tempTable WHERE NOT IN (SELECT * FROM TableMatched)
I had this situation one time. My solution was as follows.
In addition to TableA and TableMatched, there was a table that defined the rows that should exist in TableMatched for each row in TableA. Let’s call it TableMatchedDomain.
The application then accessed TableMatched through a view that controlled the returned rows, like this:
create view TableMatchedView
select a.ID,
d.Number,
m.OtherValues
from TableA a
join TableMatchedDomain d
left join TableMatched m on m.ID = a.ID and m.Number = d.Number
This way, the rows returned were always correct. If there were missing rows from TableMatched, then the Numbers were still returned but with OtherValues as null. If there were extra values in TableMatched, then they were not returned at all, as though they didn't exist. By changing the rows in TableMatchedDomain, this behavior could be controlled very easily. If a value were removed TableMatchedDomain, then it would disappear from the view. If it were added back again in the future, then the corresponding OtherValues would appear again as they were before.
The reason I designed it this way was that I felt that establishing an invarient on the row configuration in TableMatched was too brittle and, even worse, introduced redundancy. So I removed the restriction from groups of rows (in TableMatched) and instead made the entire contents of another table (TableMatchedDomain) define the correct form of the data.