MySQL Delete using subquery on same table - mysql

Using the following query, I am able to return the results I need.
SELECT t1.*
FROM lms_attendance t1
WHERE t1.id = (SELECT t2.id
FROM lms_attendance t2
WHERE t2.user = t1.user
ORDER BY t2.id DESC
LIMIT 1)
However, when trying to do a DELETE instead, this does not work. Through trial and error, I either get unknown column or can't specify target updated in from clause. The main issue here is that I absolutely have to have the WHERE clause as it is so that it returns the maximum id for each user, and not for the entire table.

Try this query below. Please run a select first to confirm if it is the correct records before running the delete. Better if you keep a backup table too.
Run select:
SELECT t1.* FROM lms_attendance t1
LEFT JOIN (SELECT user, MAX(id) id
FROM lms_attendance
GROUP BY user) t2
ON t1.id = t2.id
WHERE t2.id IS NULL
If looks OK;
DELETE t1.* FROM lms_attendance t1
LEFT JOIN (SELECT user, MAX(id) id
FROM lms_attendance
GROUP BY user) t2
ON t1.id = t2.id
WHERE t2.id IS NULL

Related

how to return all the fields of table2 based upon the occurrence of the id in the table1

I have 2 tables, one is table1
and another is table 2
I want the result by a query, like
I have tried select id from table2 order by (select id from table1); but it is giving error.
You can join and sort. But you need a column that defines the ordering of the rows in table1. Let me assume that you have such column, and that is is called ordering_id.
select t2.*
from table2 t2
inner join table1 t1 on t1.id = t2.id
order by t1.ordering_id
You can even use a subquery in the order by clause:
select *
from table2 t2
order by (select t1.ordering_id from table1 t1 where t1.id = t2.id)
Join the two tables and then order the result.But for that you need to have some column for ordering and this does not seems to be the case. Syntax you are using for ordering will not work.
SELECT A.ID, B.NAME FROM TABLE1 A INNER JOIN TABLE2 B
ON(A.ID = B.ID) ORDER BY A.ID DESC
finally got the answer
select t2.*
from table2 t2
inner join table1 t1 on t1.id = t2.id;

Join with column outside subquery

SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
WHERE ids IN (t1.values)
) as t2
WHERE t1.id = 20;
I get an error, that t1.values inside the subquery is unknown column.
You need to rewrite your query and take inne where to join condition:
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
) as t2 ON t2.ids = t1.values
WHERE t1.id = 20;
Also, you don't use amount column, so what is the point of join?
Another issue, you don't have any join condition defined.
I think you need to read about joins in SQL first :)
It seems you are trying to join database2.table to your t1 based on t1.values list.
I added group by IDs in t2 since your using aggregation function. Then, not sure what's the purpose of your sum(amount)
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount, ids
FROM database2.table
GROUP BY ids
) as t2 on t2.ids IN (t1.values)
WHERE t1.id = 20;

SQL query to have data in field instead of new record

I have searched for this but I'm probably using the wrong terminology.
The following query
SELECT t1.name, t2.entry FROM t1
INNER JOIN t2 ON t2.ID = t1.ID
WHERE t2.meta_key IN ('wp_x1','wp_x2');
Returns data similar to below where there are 2 records for each of the meta_key fields
name1,wp_x1_entry
name1,wp_x2_entry
name2,wp_x1_entry
name2,wp_x2_entry
How do I amend the query to return this instead?
name1,wp_x1_entry,wp_x2_entry
name2,wp_x1_entry,wp_x2_entry
The table/field names have been changed to hide sensitive info. Also, I know these are badly designed tables but I am unable to change the db structure.
This will be calling a mySql db from C# code.
Join another time with t2, looking for wp_x2 only
SELECT t1.name, t2.entry, t3.entry
FROM t1
JOIN t2 ON t2.ID = t1.ID and t2.meta_key = 'wp_x1'
JOIN t2 as t3 ON t3.ID = t1.ID and t3.meta_key = 'wp_x2'
Will return only rows with both wp_x1 and wp_x2. Use LEFT_JOIN if one/none is required.
Try to Group By t1.name and group_concat t2.entry.
like this :
SELECT t1.name, GROUP_CONCAT(t2.entry) FROM t1
INNER JOIN t2 ON t2.ID = t1.ID
WHERE t2.meta_key IN ('wp_x1','wp_x2')
GROUP BY t1.name;
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

In MySQL, how to use a subquery to a left join statement?

I tried to count how many new tuples are in a subset of t2 as compared to t1 by
SELECT
COUNT(t2.id)
FROM (
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
LEFT OUTER JOIN
t1
ON
t.id=t1.id
)
WHERE
t1.id IS NULL;
The subset is defined by
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
But the above program doesn't seem to work, issuing errors.
There is no need to enclose the FROM clause in (). You are referencing t2.id in your aggregate COUNT(), but your SELECT list will only produce t.id from the subquery that encapsulates t2. This version addresses the source of your errors:
SELECT
COUNT(t.id) AS idcount
FROM
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
LEFT OUTER JOIN t1 ON t.id = t1.id
WHERE t1.id IS NULL
However:
Since your subquery is actually pretty simple, I believe it isn't necessary at all. The whole thing can be done with a LEFT JOIN:
SELECT
/* The equivalent of COUNT(*) in this context */
COUNT(t2.id) AS idcount
FROM
t2
LEFT OUTER JOIN t1 ON t2.id = t1.id
WHERE
t1.id IS NULL
AND (t2.col2 = 0 AND t2.col3 = 0)
are you sure you don't want to do COUNT(t.id)? t2 is in a subquery and is not available to the main query only t and t1 are available.
The problem is the alias. You have:
select count(t2.id)
But, t2 is defined in the subquery, so it is out of scope.
You want:
select count(t.id)

DELETE + JOIN + ORDER BY + LIMIT = syntax error

Drop the ORDER BY + LIMIT, or the JOIN, and everything is peaches. Put them together and I seem to release the Kraken. Anyone who can shed some light?
DELETE table1 AS t1
FROM table1 AS t1 LEFT JOIN table2 AS t2 ON t1.id = t2.id
WHERE t2.field = 'something'
ORDER BY t1.id DESC
LIMIT 5
(Delete using aliases)
I've also tried it without aliases & dropping the WHERE, to no avail. Always a syntax error "near 'ORDER BY...".
From Mysql Docs: DELETE
For the multiple-table syntax, DELETE deletes from each tbl_name the rows that satisfy the conditions. In this case, ORDER BY and LIMIT cannot be used.
In your case, I think this works:
DELETE
FROM table1
WHERE EXISTS
( SELECT t2.id
FROM table2 AS t2
WHERE t2.id = table1.id
AND t2.field = 'something'
)
ORDER BY id DESC
LIMIT 5
If you really need to do this you can do the following
DELETE table1
WHERE id in
(SELECT t.id
FROM table1 AS t INNER JOIN table2 AS t2 ON t1.id = t2.id
WHERE t2.field = 'something' --No point in doing a LEFT JOIN because of this
ORDER BY t1.id DESC
LIMIT 5)
t1 was not declared as an alias. Try t everywhere you have t1 (or vice versa).