Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Hemnyos's avatar

SQL SELECT and DELETE

Hi ! I'm doing a project with laravel and i need a command to SELECT 'STDDEV' and DELETE it on the same query, but i can't, cuz of syntax, i dont understand where is the problem, can someone help me pls ? T_T

Yes, i'm a newbie. <3

SELECT audits.slug,
AVG(DISTINCT audits.score) AS moyenne, STDDEV(audits.score) AS ecart
FROM audits
GROUP BY audits.slug
ORDER BY ecart DESC;
DELETE FROM audits 
HAVING STDDEV(audits.score) AS ecart < 30 ORDER BY audits.slug; 

and this is my error : SQL error (1064) you have an error in your sql syntax..... right syntaxe to use near 'Having stddev(audits.score) as ecart < 30 Order by audits.slug' at line 2.

0 likes
50 replies
Sinnbeck's avatar

I dont think there is any way to both select and delete in the same query. Run one query to delete and one to select.

Hemnyos's avatar

@Sinnbeck i thought with the ";" u can do both in the same query. But i'm learning, so if u tell it, i trust u ^^

Sinnbeck's avatar

@Hemnyos Ah didnt notice that. I still recommend doing 2 queries as you wouldn't be able to get the result of the select anyways if it had worked:) You can wrap them in a transaction if they "depend" on each other

If you show the laravel code, we can help you

Hemnyos's avatar

@Sinnbeck

public function handle()
    {

        //DB size
        \DB::statement(
            "SELECT table_name AS 'Table',
                   ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
                   FROM information_schema.TABLES
                   WHERE table_schema = 'reporting'
                   ORDER BY (data_length + index_length) DESC"
                   );

        //Delete 'script-treemap-data'
        \DB::statement(
            "DELETE audits
                   FROM audits
                   WHERE audits.slug = 'script-treemap-data'"
                   );

        //ecart 'Score'
        \DB::statement(
            "SELECT audits.slug,
                   AVG(DISTINCT audits.score) AS moyenne, STDDEV( audits.score) AS ecart_type
                   FROM audits
                   GROUP BY audits.slug"
                  );
        }


}

The last is not complete cuz i'm testing on MYSQL first.

Sinnbeck's avatar

@Hemnyos First off I suggest learning the query builder in laravel and use that. Secondly, you are just throwing away the select results. :)

Example

\DB::table('audits')->where('slug', 'script-treemap-data')->delete();
1 like
Hemnyos's avatar

@Sinnbeck yeah i'm not a huge fan of eloquent yet, sql was easier xD sorry and thx

Sinnbeck's avatar

@Hemnyos Ok fair enough. But as I said, your selects does nothing :) You never get the result. Are the queries perhaps meant to be just 1 big query for what to delete?

Hemnyos's avatar

@Sinnbeck does nothing yet. I'm just testing in my sql for now. But i'll like to do it in 1 query. Select and give me the standart deviation and delete the one with low stats. like STDDEV < 30

Sinnbeck's avatar

@Hemnyos then it's all 1 query. That's how sql works :) even if you run 2 queries after each other, they have no influence on each other

1 like
Sinnbeck's avatar

Your query needs to be something like

\DB::statement(
            "DELETE audits
                   FROM audits
                   WHERE audits.slug = 'script-treemap-data'
                    AND WHERE report_id IN (SELECT id FROM reports WHERE...) 
                  "); 
1 like
Hemnyos's avatar

@Sinnbeck oh ok i got it ! so i have to do 3 independant queries or 1 for the 3 things.

Sinnbeck's avatar

@Hemnyos Ill try explain again :)

Take this query.

 \DB::statement(
            "SELECT table_name AS 'Table',
                   ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
                   FROM information_schema.TABLES
                   WHERE table_schema = 'reporting'
                   ORDER BY (data_length + index_length) DESC"
                   );

You get some rows from the database, but as you never use it for anything, its wasted

To get the actual result, you need to tell the DB to actually select the rows

$rows =  \DB::select(
            "SELECT table_name AS 'Table',
                   ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
                   FROM information_schema.TABLES
                   WHERE table_schema = 'reporting'
                   ORDER BY (data_length + index_length) DESC"
                   );
dump($rows);

Now you have the data available in php and can use it in other queries. But for mysql, the query is already gone in both cases. So when you run the DELETE, mysql has no knowledge that you just did a SELECT.

And to actually delete based on some data, you can either use a subselect as I gave an example of before.

Or you can pass data to mysql using php

$deleteThese = [1,2,3];

\DB::statement(
            "DELETE audits
                   FROM audits
                   WHERE audits.slug = 'script-treemap-data'
                    AND WHERE report_id IN (?, ?, ?)
                  ", $deleteThese); 
2 likes
Hemnyos's avatar

@Sinnbeck Really thx i understand now, what did u mean ! and for the last i try :

  $deviation = \DB::select(
            "SELECT STDDEV(audits.score) AS ecart
                   FROM audits
                   GROUP BY audits.slug
                   ORDER BY ecart DESC"
                  );
        //dump($deviation);

        \DB::delete(
            "
                DELETE audits FROM audits WHERE ecart IN $deviation < 30
            ");
````

but the column 'ecart' dont really exist cuz its just STDDEV as ecart. so i dont know how to choose only TDDEV > 30 and delete < 30 :/
Sinnbeck's avatar

@Hemnyos You still need to select some IDS, if you want something to delete by. And the first query should only use the STDDEV in a where clause. Start by writing a query in your database editor, that returns only the rows you wish to delete. Just the plain rows.. Then once it works, post it here and I can give you some suggestions :)

1 like
Hemnyos's avatar

@Sinnbeck

SELECT audits.id, AVG(audits.score) AS score,
STDDEV(audits.score) AS ecart
FROM audits
GROUP BY audits.id
ORDER BY ecart DESC;

And i just want to delete audits < 30 for example bout stddev

Sinnbeck's avatar

@Hemnyos That is still not filtered? No where clause. Is is because you want to filter it with php?

If you just send it directly to the DELETE query, it will delete all rows. :)

1 like
Hemnyos's avatar

@Sinnbeck hum... if i had a where, got a syntax error :/ i do it wrong i think. U_U

Sinnbeck's avatar

@Hemnyos something like this. I removed the group by as I assume ids are unique (or did you group on the wrong thing?)

SELECT audits.id
FROM audits
WHERE STDDEV(audits.score) > 12;
1 like
Hemnyos's avatar

@Sinnbeck I did it !

SELECT audits.id, AVG(audits.score) AS score, STDDEV(audits.score) AS ecart
FROM audits
WHERE 30 < (SELECT STDDEV(audits.score) AS ecart FROM audits)
GROUP BY audits.id;
````
Sinnbeck's avatar

@Hemnyos great. You can extract the ids with $ids = collect($deviation)->pluck('id');

Sinnbeck's avatar

@Hemnyos yeah. Something like this. Be aware that this is prone to sql injection. That's why we use the query builder or eloquent

\DB::statement(
            "DELETE audits
                   FROM audits
                   WHERE audits.slug = 'script-treemap-data'
                    AND WHERE report_id IN (". $ids->implode(','). ")
                 " ); 
1 like
Sinnbeck's avatar

@Hemnyos So just delete every single row? No need to a select() with a delete() btw :)

Sinnbeck's avatar

@Hemnyos The query you are showing deletes everything. You arent passing it any ids, so it knows nothing about what to delete. Here is how you tell it to only delete those ids

 \DB::table('audits')->whereIn('id', $ids)->delete();
1 like
Hemnyos's avatar

@Sinnbeck ooooh i try eloquent but i dont understand how to give him the "$ids". ok, rlly thx

Hemnyos's avatar

@Sinnbeck thx for the help and thx for all of your kidness :) have a nice day !

tykus's avatar

The SELECT and DELETE queries would be independent anyway; what was the purpose of making the SELECT query?

Hemnyos's avatar

@tykus a command to delete audits with a weak standard Deviation

Hemnyos's avatar

@tykus But i want to select first to have standard deviation isnt in the database and delete when it is too low

tykus's avatar

@Hemnyos where are you using the result of the SELECT queries; you're not...

tykus's avatar

@Hemnyos SELECT is a read-only operation; it has no side-effects that are usable for the other query(ies)

Hemnyos's avatar

@tykus the first select is just to read yes. But the last i want to see and delete the low results

tykus's avatar

@Hemnyos yeah... that's not what you're doing though. As mentioned several times earlier - the SELECT queries are redundant in your command.

tykus's avatar

@Hemnyos no, not at all; whether you use Eloquent, or Query Builder or raw SQL statements... it all becomes SQL in the end.

You are missing the earlier point (i) the queries are independent from one another (ii) the SELECT queries have no side-effects to organise/write data for the DELETE query (iii) you never use the results of the SELECT queries.

You need to write your DELETE query such that it deletes the correct record(s)

Hemnyos's avatar

@tykus ya but the STDDEV doesnt exist in the database, its just cuz i select first and do the calcul. So, i can't delete without select (for the calcul) first. Or i can do the calcul AND delete on the same ?

tykus's avatar

@Hemnyos you can calculate the STDDEV in the DELETE query.

Again, for the umpteenth time (i) the queries are independent from one another (ii) the SELECT queries have no side-effects to organise/write data for the DELETE query (iii) you never use the results of the SELECT queries

tykus's avatar

@Hemnyos and yet...

Anyway, how do determine which records to delete if this is an aggregated query result???

Hemnyos's avatar

@tykus Again, i'm learning. But my 3 queries r independant from one another and my first select is juste here to show me my stats (size) so i'll dont use it. my second queries is to delete 1 row. and the first have to calculate and delete the low results.

but i'm not an english guy, maybe i dont understand what do you mean.

Please or to participate in this conversation.