Remove anything above 900 rows in MariaDB - mariadb

This works in Mysql, but it seems that the syntax for MariaDB is different, I am trying to remove anything above the first 900 returned rows (LIMIT 900) :
DELETE FROM cronschedule NOT IN (SELECT * FROM cronschedule LIMIT 900);
Trying to do this in Maria though returns the following error :
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near
'NOT IN (SELECT * FROM cronschedule LIMIT 900)' at line 1
So how would I do this in Maria?

I'd expect this to be a bit more efficient than your answer with the LEFT JOIN / IS NULL construction:
DELETE cr.*
FROM cronschedule cr
JOIN
(
SELECT id
FROM cronschedule ii
ORDER BY
id ASC
LIMIT 1 OFFSET 900
) i2
ON cr.id >= i2.id ;

This seems to work
DELETE cr.*
FROM cronschedule cr
LEFT JOIN
(
SELECT id
FROM cronschedule ii
ORDER BY
id ASC
LIMIT 900
) i2
ON cr.id = i2.id
WHERE i2.id IS NULL;

Related

mariadb alternative to outer apply or lateral?

What I wanted was to use CROSS APPLY, but I guess that doesn't exist in mysql. The alternative I've read is LATERAL. Well, I'm using mariadb 10.3 and I guess that doesn't exist either. The ticket table contains an id that's referenced by the ticket_id column in the note table. A ticket can have many notes, I'm trying to list all tickets with their most recent note date (post_date). How could I write the query below for mariadb?
SELECT t.*, n.post_date
FROM ticket t,
LATERAL (
SELECT note.post_date FROM note WHERE t.id = note.ticket_id ORDER BY note.post_date DESC LIMIT 1
) n;
Example table structure:
Ticket
id
subject
1
stuff
2
more
note
id
post_date
ticket_id
1
1
2
1
3
2
4
1
5
2
I did find an open jira ticket from people asking for mariadb to support lateral.
From what I read, LATERAL will not be supported in MariaDB until version 11. But we can just as easily use ROW_NUMBER here, which is supported:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ticket_id ORDER BY post_date DESC) rn
FROM note
)
SELECT t.*, n.post_date
FROM ticket t
INNER JOIN cte n
ON n.ticket_id = t.id
WHERE n.rn = 1;
If you wanted a close translation of your current lateral join, then use:
SELECT t.*,
(SELECT n.post_date
FROM note n
WHERE t.id = note.ticket_id
ORDER BY n.post_date DESC
LIMIT 1)
FROM ticket t;

Spool space error when inserting large result set to table

I have a SQL query in teradata that returns a results set of ~160m rows in (I guess) a reasonable time: dependent on how good a day the server is having it runs between 10-60 minutes.
I recently got access to space to save it as a table, however using my initial query and the "insert into " command I get error 2646-no more spool.
query structure is
insert into <test_DB.tablename>
with smaller_dataset as
(
select
*
from
(
select
items
,case items
from
<Database.table>
QUALIFY ROW_NUMBER() OVER (PARTITION BY A,B ORDER BY C desc , LAST_UPDATE_DTM DESC) = 1
where 1=1
and other things
) T --irrelevant alias for subquery
QUALIFY ROW_NUMBER() OVER (PARTITION BY A, B ORDER BY C desc) = 1)
, employee_table as
(
select
items
,max(J1.field1) J1_field1
,max(J2.field1) J2_field1
,max(J3.field1) J3_field1
,max(J4.field1) J4_field1
from smaller_dataset S
self joins J1,J2,J3,J4
group by
non-aggregate items
)
select
items
case items
from employee_table
;
How can I break up the return into smaller chunks to prevent this error?

Update another table using output of cte in teradata

Technology: Teradata 16.20
I'm trying to update a table, that takes data from another table which uses CTE data.
I'm getting below error:
Error:
select failed 3707 syntax error, expected something like a 'SELECT' keyword or '(' or a 'TRANSACTIONTIME' keyword or a 'VALIDTIME' keyword between ')' and the 'UPDATE' keyword
Question:
Is it possible to update a table using another table that is getting joined with cte?
I know it can be done with a volatile table. I have seen CTE with insert statement and with select statement, but never seen cte with an update statement. Writing the same sql over and over for multiple self join only increases the lines of code. If this update can be done using CTE, that would be much easier and understandable
Code:
WITH NAME_CTE AS (
SELECT FIRST.ID,FIRST.NAM,LAST.NAME
FROM TABLE_FIRST FIRST INNER JOIN TABLE_LAST LAST
ON FIRST.ID = LAST.ID
)
UPDATE SUBJECT_TEACHER_TABLE
FROM (
SELECT CROSS_TBL.SUB_ID,
COALESCE(CTE1.NAM,CTE1.NAME,CTE2.NAM,CTE2.NAME) AS FINAL_NAME
FROM CROSS_REFERENCE_TABLE CROSS_TBL
LEFT JOIN NAME_CTE CTE1 ON CROSS_TBL.CR_ID1 = CTE.ID
LEFT JOIN NAME_CTE CTE2 ON CROSS_TBL.CR_ID2 = CTE.ID
) PV
SET
FINAL_NAME = PV.FINAL_NAME
WHERE SUBJECT_TEACHER_TABLE.SUB_ID = PV.SUB_ID;
Modified Query: As per #dnoeth suggesstion
UPDATE SUBJECT_TEACHER_TABLE
FROM (
WITH NAME_CTE AS (
SELECT FIRST.ID,FIRST.NAM,LAST.NAME
FROM TABLE_FIRST FIRST INNER JOIN TABLE_LAST LAST
ON FIRST.ID = LAST.ID)
SELECT CROSS_TBL.SUB_ID,
COALESCE(CTE1.NAM,CTE1.NAME,CTE2.NAM,CTE2.NAME) AS FINAL_NAME
FROM CROSS_REFERENCE_TABLE CROSS_TBL
LEFT JOIN NAME_CTE CTE1 ON CROSS_TBL.CR_ID1 = CTE.ID
LEFT JOIN NAME_CTE CTE2 ON CROSS_TBL.CR_ID2 = CTE.ID
) PV
SET
FINAL_NAME = PV.FINAL_NAME
WHERE SUBJECT_TEACHER_TABLE.SUB_ID = PV.SUB_ID;
Error:
SQL Error [3807] [42S02]: [Teradata Database] [TeraJDBC 15.10.00.22] [Error 3807] [SQLState 42S02] Object 'NAME_CTE' does not exist.

Oracle - Invalid relational operator when I'm using EXISTS

I have the following query that was given to me, where the returned record is removed from the table et_fact_reclam_ter_his_misc when the condition is met:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped IN
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS (SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest));
I've been searching, and found that using EXISTS instead of IN will improve query performance. But I have run into 2 errors. The first is an error message that appears when I replace the IN operator with EXISTS:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped EXISTS
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS (SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest));
ORA-00920: invalid relational operator
The second is when I try to nest a SELECT inside the DELETE, but the number of rows returned are different:
DELETE FROM et_fact_reclam_ter_his_misc
WHERE EXISTS
(SELECT FROM et_fact_reclam_ter_his_misc
WHERE num_siniest || num_exped IN
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1
WHERE NOT EXISTS
(SELECT *
FROM et_fact_reclam_ter_misc t2
WHERE t1.num_siniest = t2.num_siniest)));
I appreciate any help to improve query performance
Could you try below, not the best approach to concatenate fields for joins,
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT DISTINCT num_siniest || num_exped
FROM et_fact_reclam_ter_his_misc t1) B
WHERE A.num_siniest|| A.num_exped = B.num_siniest || B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
Seems like the concatenated columns are numbers and it would force oracle to cast it to char which could hinder performance.Below one should be faster if you are dealing with lots of records.
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT DISTINCT num_siniest, num_exped
FROM et_fact_reclam_ter_his_misc t1) B
WHERE A.num_siniest = B.num_siniest
AND A.num_exped = B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
DISTINCT will overkill, substituting with group by will definitely be far better, so the best one will be :
DELETE FROM et_fact_reclam_ter_his_misc A
WHERE EXISTS
( SELECT 1 FROM
(SELECT num_siniest, num_exped,count(1)
FROM et_fact_reclam_ter_his_misc t1
group by num_siniest, num_exped) B
WHERE A.num_siniest = B.num_siniest
AND A.num_exped = B.num_exped
AND NOT EXISTS (SELECT 1
FROM et_fact_reclam_ter_misc t2
WHERE B.num_siniest = t2.num_siniest));
Looks like this might do it:
delete et_fact_reclam_ter_his_misc t1
where not exists
( select * from et_fact_reclam_ter_misc t2
where t2.num_siniest = t1.num_siniest
);
In the original version, the first level subquery seems to be querying the same table that is being deleted, just in order to construct a not exists subquery. I suspect that all you want to do is delete his rows where num_siniest does not exist in the main table. Some sample data and expected results would make this clearer.

SQLITE - Delete rows with self join?

I am trying to delete all rows in a simple table that have a duplicate value except for the duplicate with the highest id.
Table:
CREATE TABLE IF NOT EXISTS [Expression] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Value] VARCHAR(2048) NOT NULL
)
Attempted Queries:
DELETE Expression
WHERE EXISTS (
SELECT 1
FROM Expression Exp2
WHERE Expression.Value=Exp2.Value
AND Expression.Id < Exp2.Id)
fails with
"SQL logic error or missing database near "Expression":syntax error"
DELETE Exp1
FROM Expression Exp1
INNER JOIN Expression Exp2
ON Exp1.Value=Exp2.Value AND Exp1.Id < Exp2.Id
fails with
"SQL logic error or missing database near "Exp1":syntax error"
What syntax do I need to use?
Don't forget the FROM.
DELETE command
DELETE FROM Expression
WHERE EXISTS (
SELECT 1
FROM Expression Exp2
WHERE Expression.Value=Exp2.Value
AND Expression.Id < Exp2.Id
);
You can do this with many ways:
1) USING CTE:
WITH CTE AS (
SELECT ID, VALUE, ROW_NUMBER() OVER(ORDER BY Value) as RowNum
FROM Expression
)
DELETE
FROM CTE
WHERE ROWNum >1
2) USING Temp tables: Same concept
DELETE t1 FROM contacts t1 INNER JOIN contacts t2 WHERE t1.id < t2.id AND t1.email = t2.email;

Resources