Delete STATEMENT with InnerJoin Firebird

2020-04-16 19:20发布

问题:

I made this select statement to find duplicated rows I want to delete. I though that I simply change SELECT TO DELETE and It'd delete rows, but it didn't.

This is select statement:

select * FROM MYCARD T1
INNER JOIN( SELECT IDCARD, YEAR, MONEY FROM MYCARD GROUP BY IDCARD, YEAR, MONEY HAVING COUNT(IDCARD) > 1 ) T2 ON
T1.IDCARD = T2.IDCARD AND T1.YEAR=T2.YEAR
AND T1.MONEY = T2.MONEY
WHERE T1.IDMONEY = 5 AND IDCARD=80
AND ID not in (select min(ID)
from MYCARD
WHERE IDMONEY=5
AND IDCARD=80
group by IDCARD, YEAR);

and I wanted to use this delete:

DELETE FROM MYCARD T1
INNER JOIN( SELECT IDCARD, YEAR, MONEY FROM MYCARD GROUP BY IDCARD, YEAR, MONEY HAVING COUNT(IDCARD) > 1 ) T2 ON
T1.IDCARD = T2.IDCARD AND T1.YEAR=T2.YEAR
AND T1.MONEY = T2.MONEY
WHERE T1.IDMONEY = 5 AND IDCARD=80
AND ID not in (select min(ID)
from MYCARD
WHERE IDMONEY=5
AND IDCARD=80
group by IDCARD, YEAR);

But it doesn't work. Any ideas?

I also tried this:

DELETE FROM MYCARD
WHERE EXISTS (select * FROM MYCARD T1
INNER JOIN( SELECT IDCARD, YEAR, MONEY FROM MYCARD GROUP BY IDCARD, YEAR, MONEY HAVING COUNT(IDCARD) > 1 ) T2 ON
T1.IDCARD = T2.IDCARD AND T1.YEAR=T2.YEAR
AND T1.MONEY = T2.MONEY
WHERE T1.IDMONEY = 5 AND IDCARD=80
AND ID not in (select min(ID)
from MYCARD
WHERE IDMONEY=5
AND IDCARD=80
group by IDCARD, YEAR))

回答1:

It doesn't work, because joins are not part of the Firebird delete syntax.

You need to use a delete with an exists, for example

delete from mycard t1
where exists (
   <a correlated subquery to identify the rows to delete>
)

or a similar way to identify the records to delete. Bottomline is: all logic necessary needs to be in the where clause.

Given the example, you need to do something like:

DELETE FROM MYCARD T1
WHERE T1.IDMONEY = 5 AND T1.IDCARD = 80
AND EXISTS (
    SELECT IDCARD, YEAR, MONEY 
    FROM MYCARD T2
    WHERE T2.IDCARD = T1.IDCARD 
    AND T2.YEAR = T1.YEAR
    AND T2.MONEY = T1.MONEY
    GROUP BY T2.IDCARD, T2.YEAR, T2.MONEY 
    HAVING COUNT(T2.IDCARD) > 1
)
AND T1.ID not in (
    select min(ID)
    from MYCARD
    WHERE IDMONEY = 5
    AND IDCARD = 80
    group by IDCARD, YEAR
)

You may need to add an additional AND T2.IDMONEY = 5 in the select in the exists (unless money and idmoney are the same thing).



标签: sql firebird