I need to do selection from mysql 5.7.22 in one query.
select id from t1 where type_id=(select type_id from t2 where id=1 limit 1) and id not in
(select obj_id from t2
where
type_id = (select type_id from t2 where id=1 limit 1)
and
type2_id = (select type2_id from t2 where id=1 limit
...
)
I have some duplicate subquerys in where clause (it's only part of the query, this subquery duplicates many times)
'(select type_id from t2 where id=1 limit 1)'
Can I some how figure it out in one place, to reduce verbose.
So I want to select once
select type_id, type2_id from t2 where id=1 limit 1
and make type_id, type2_id available in all query context.
I know mysql 8.0 has WITH syntax, but I am using 5.7.22
I want to do this in one query without transactions.
It's hard to give you complete advice without seeing your more of your query. But you have some choices.
You could try creating a view as follows then using it.
CREATE VIEW selector
AS SELECT MAX(type_id) type_id, MAX(obj_id) obj_id
FROM t2
WHERE id = 1
It looks possible that the t2 query returns multiple rows. This view deals with that by using MAX() instead of LIMIT 1. But if t2.id is a primary key, then all you need is
CREATE VIEW selector
AS SELECT type_id, obj_id
FROM t2
WHERE id = 1
Then you can use the view in your query.
For example
SELECT id
FROM t1
WHERE type_id = (SELECT type_id FROM selector)
AND obj_id <> (SELECT obj_id FROM selector)
Or you could figure out how to use join operations rather than subqueries.
SELECT id
FROM t1
JOIN selector ON t1.type_id = selector.type_id AND t1.obj_id <> selector.obj_id
try this
select id from t1 ,(select type_id from t2 where id=1 limit 1) t where type_id=t.type_id and id not in
(select obj_id from t2
where
type_id = t.type_id
and
type2_id = t.type_id
...
)
Related
the sql as follows come from mysql document. it is:
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
The document say It finds all rows in table t1 containing a value that occurs twice in a given column , and doesnot explain the sql.
t1 and t is the same table, so the
count(*) in subquery == select count(*) from t
, isn't it?
count(*) in subquery == select count(*) from t
is wrong. because in mysql you can't use it like that. so you have to run it like that to get result of same id having two rows.
if you want to get count of same occurrence,
SELECT id, name, count(*) AS all_count FROM t1 GROUP BY id HAVING all_count > 1 ORDER BY all_count DESC
And also you can get values as your query like this as well,
select * from t1 where id in ( select id from t1 group by id having count(*) > 1 )
The query contains a correlated subquery in WHERE clause:
SELECT COUNT(*) FROM t1 WHERE t1.id = t.id
It is called correlated because it is related to the main query via t.id. So, this subquery counts the number of records having an id value that is equal to the current id value of the record returned by the main query.
Thus, predicate
(SELECT COUNT(*) FROM t1 WHERE t1.id = t.id) = 2
evaluates to true for any row with an id value that occurs twice in the table.
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
This query goes through each record in t1 and then in the subquery looks into t1 again to see if in this case id is found 2 times (and only 2 times). You can do the same for any other column in t1 (or any table for that matter).
When you would like to see all values that are multiple times in the table, change WHERE 2 = by WHERE 1 <. This will also give you the values that are 3 times, 4 times, etc. in the table.
{
SELECT id,count( * )
FROM
MyTable
group by id
having count( * )>1
}
with this code, you can see the rows which repet more than one,
and you can change this query by yourself
How about using GROUP BY and HAVING:
SELECT id, count(1) as Total FROM MyTable AS t1
GROUP BY t1.id
HAVING Total = 2
Is there a way to tell MySQL that while making something like this
SELECT id, MAX(seq) FROM t1 GROUP BY ident;
I can also get the id value? I know I shouldn't be using id if it's not in a group by but I feel like its strange to make a multi pass to get the row ids with the maximum seq field when it already passed it. So what is the most effective way to do this? id is the primary key
SELECT a.*
FROM tableName
INNER JOIN
(
SELECT ident, MAX(seq) seq
FROM tableName
GROUP BY ident
) b ON a.ident = b.ident AND
a.seq = b.seq
Mabye:
SELECT MAX(a.seq), (SELECT id FROM t1 as b where b.ident=a.ident AND MAX(a.seq) = b.seq LIMIT 1) as id FROM t1 AS a GROUP BY a.ident;
Fiddle
Try using self-join:
SELECT t1.* FROM MyTable t1
JOIN
(SELECT ident, MAX(seq) AS MAX_Seq
FROM MyTable
GROUP BY ident
) t2
ON t1.seq = t2.MAX_Seq
AND t1.ident = t2.ident
See this sample SQLFiddle
What is seq exactly ?
I guess you can also order your results ?
SELECT id FROM t1 GROUP BY ident ORDER BY seq DESC
Regarding to the others answer, seq is in another table ?
I'm not a SQL guy, and I've just tried every JOIN MySQL offers.
I primarily need data from view1 using WHERE, ORDER BY, LIMIT with offset (the data is incorrect without those conditions.)
view1 is not limited by view2
Data also needs to be pulled from view2, but view2 has its' own WHERE (or whatever's best) condition
view2 may not have corresponding data, but it shouldn't be grabbed without being linked to view1 (NULLs are just fine!)
I'll just give you the two SELECTs that work for me rather than the hashes I've come up with.
For view1:
SELECT * FROM view1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC LIMIT index1, count1;
(index1 and count1 are INs i use for a stored proc)
For view2:
SELECT * FROM table2
WHERE column1 = ? AND table1_id IN (
SELECT id FROM view1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC LIMIT index1, count1
)
GROUP BY table1_id
(? is any arbitrary value i put in)
I'm at wits end. I have no idea how to fuse these two.
Specifics
Please note that the IN for view2 is almost identical to the view1 query. Thanks!
You can write a subquery for table2 and add WHERE clause there, also you can add WHERE clause at the ent of the query -
SELECT * FROM table2 t2
JOIN (
SELECT id FROM table1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC
LIMIT index1, count1
) t1
ON t1.id = t2.table1_id
WHERE
t2.column1 = ?
GROUP BY
t2.table1_id
In this example I used JOIN instead of WHERE IN condition.
How about this query:
Select t1.id
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.table1_id
WHERE t1.column1 IS NULL OR t1.column1 = 1
i think it should help you
Select TableName1.id
FROM TableName1
JOIN TableName2 ON TableName1.id = TableName2.id
WHERE TableName1.column1 IS NULL OR TableName1.column1 = 1
I know this sounds rather confusing but I'm at a loss how to explain it better. I have a table simplified below:
DB Type ID
================
Table1 1
Table1 2
Table1 3
Table1 4
Table1 5
Table2 6
Table2 7
Table2 8
Table2 9
Table2 10
what i am trying to achieve is to basically clean out this table but keep the record with the highest ID for each DB Type if that makes sense - so in this case it would be (Table1,5) and (Table2,10) with all other records being deleted. Is it possible to do this exclusively through MySQL?
*EDIT***
Answer thanks to tips from Yogendra Singh
DELETE FROM MyTable WHERE ID NOT IN (SELECT * FROM (SELECT MAX(ID) from MyTable GROUP BY DB Type) AS tb1 ) ORDER BY ID ASC
TRY selecting the max ID group by db_type first and then use it as sub query with not in.
DELETE FROM MyTable
WHERE ID NOT IN
(SELECT ID FROM
(SELECT MAX(ID) AS ID from MyTable GROUP BY DB Type) AS tb1
)
EDIT:
DELETE FROM MyTable
HAVING MAX(ID) > ID;
delete your_table
from
your_table left join
(select max(id) max_id from your_table group by type) mx
on your_table.id=mx.max_id
where mx.max_id is null
Subquery returns the maximum id for every type, and those are the values to keep. With an left join i'm selecting all the rows from your table that don't have an in in max_ids, and those are the rows to delete. This will work only if id is primary key, otherwise we have to join also the type.
Is the combination DB Type - ID unique?
If so, you can attack this in two stages:
Get only the rows you want
SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable
GROUP BY [DB Type]
Delete the rest (Wrapping the previous statement into a more complicated statement; don't mean that)
DELETE FROM YourTable
FROM
YourTable
LEFT JOIN
(SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable GROUP BY [DB Type]) DontDelete
ON
YourTable.[DB Type]=DontDelete.[DB Type] AND
YourTable.ID=DontDelete.MaxID
WHERE
DontDelete.[DB Type] IS NULL
DELETE FROM MyTable del
WHERE EXISTS (
(SELECT *
FROM MyTable xx
WHERE xx."db Type" = del."db Type"
AND xx.id > del.id
);
delete from my_Table
where Day in (select MAX(day) d from my_Table where id='id')
I have two different tables
in first one (t1) I have
Table [t1]
id Product_URL
.
Table [t2]
id Product_id Product_URL
I would like to UPDATE ALL product_id field (from t2) to the id of the first
WHERE t1.product_url = t2.product_url
can I do that In one query?
UPDATE t2
JOIN (
SELECT t2_2.id, t1.id as new_id
FROM
t2 t2_2 JOIN
t1 ON t2_2.product_url = t1.product_url AND t2_2.product_id <> t1.id
ORDER BY t2_2.id
LIMIT 5000
) sub ON t2.id = sub.id
SET id = sub.new_id;
EDIT: It looks like mutli-table updates do not play well with LIMIT and ORDER BY, but here's another query that accomplishes the same thing...