I need to get a subset of one of my tables, and then use these id's in another query, is this possible?
Ideally, I need to use the result of this query:
SELECT id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1
inside this query:
UPDATE table
SET col1 = CONCAT(col1, '_1')
WHERE id IN (ABOVE_QUERY)
I think you are looking for something like this:
UPDATE
table INNER JOIN (SELECT MAX(id) as m_id
FROM table
GROUP BY col1, co12
HAVING COUNT(*) > 1) t1
ON table.id = t1.m_id
SET col1 = CONCAT(col1, '_1')
In MySQL you need to use a JOIN because you aren't allowed to update a table referenced in a subquery. And you probably need to use an aggregated function on the ID returned by your subquery.
Related
I have table 1 which contains unique values and table 2 which contains multiple values for the same email. What I want to do is select the first value of 'id' - table 2 contains a number of ids and matching emails
SELECT DISTINCT
table1.email,
table2.id FROM
table1
INNER JOIN users ON table1.email = table2.Email
the problem is the output needs to be unique - i.e. one ID - the first one from table2 that is associated with a given email - currently we're getting multiple results - no unique or distinct values.
Probably
any id - add ORDER BY RAND()
1 row of result - add LIMIT 1.
So, the query might be something like this:
SELECT DISTINCT
table1.email,
table2.id
FROM table1
INNER JOIN table2 ON table1.email = table2.email
ORDER BY RAND()
LIMIT 1
Based on new information, it seems like you're looking for something like this instead:
Note: Works on MySQL v8+ and MariaDB 10.2+ that have window function:
SELECT email, id
FROM
(SELECT table1.email,
table2.id,
ROW_NUMBER()
OVER
(PARTITION BY table1.email ORDER BY table2.id) AS 'RowNumber'
FROM table1
INNER JOIN table2 ON table1.email = table2.email) t
WHERE RowNumber=1;
Assign ROW_NUMBER() with table1.email as partition and sort by table2.id ascending (note that the default sorting of ORDER BY is ascending so there's no need to define it as ORDER BY xxx ASC).
Turn the base query into a subquery then do a SELECT .. with condition of WHERE RowNumber=1. Hence, it will return only a single row for each email.
Alternatively, depending on your data, you could just simply do something like this:
SELECT table1.email,
MIN(table2.id) AS minID
FROM table1
INNER JOIN table2 ON table1.email = table2.email
GROUP BY table1.email;
Demo fiddle
I have a table with 2 columns, each column is a FK to the same entity
Col1 and col2 are unique
I'm looking to create a query that recursively attempt a self join from Col2 -> Col1 based upon the IDs being the same on Col2 and Col1 between different rows
I cannot fathom this further than:
select *
from table as t1
join table as t2 on t1.col2 = t2.col1
That query only does a single join but i'd like to keep joining for as long as it is successful to retrieve a sum of successful joins
It's not possible for me to manually write the joins because there could potentially be none, one or many joins
You can use recursive cte to achieve this.
Sample example
With recursive cte(id) as
(Select 1 as id from dual
Union all
Select id +1 from cte where id < 10)
Select * from cte;
Here values will recusively generate untill it reaches value of 10.
Have a table where certain rows come in couples which have a matching GUID. Just wondering how to SELECT all data from the table but ONLY if the rows exist as a couple with a matching GUID.
You can use a query like this:
SELECT *
FROM yourtable
WHERE GUID IN (SELECT GUID FROM yourtable GROUP BY GUID HAVING COUNT(*)=2)
The subquery will return all GUIDs that appears exactly twice, the outer query will return all rows associated to those GUIDs.
Please see fiddle here.
Try something like this:
SELECT t1.*
FROM
table t1
, table t2
WHERE
t1.guid = t2.guid
AND t1.id <> t2.id
;
table: your table name
id: some field that you know is different for both rows
Try
SELECT t.*
FROM Table1 t JOIN
(
SELECT guid
FROM Table1
GROUP BY guid
HAVING COUNT(*) = 2
) q ON t.guid = q.guid
Here is SQLFiddle demo
im using the IN() function to match againts some ids.
SELECT * FROM my_table WHERE id IN(id1,id2,id3)
the thing is, now i need to calculate a SUM() based on the matched id, and i would like to do it on the same query. Something like
SELECT *,(SELECT SUM() WHERE id = the_matched_id) FROM my_table WHERE id IN(id1,id2,id3)
¿is it possible? maybe i should consider to change my query, or do it separately. ¿ What a do you suggest?
Thanks!
The matched ID is just the ID of each row from the outer table. You can use different aliases to compare these IDs.
SELECT *, (SELECT SUM(summableColName) FROM my_table t2 WHERE t2.id = t1.id)
FROM my_table t1 WHERE id IN (id1, id2, id3)
Try something like
SELECT id,sum(field) FROM my_table WHERE id IN(id1,id2,id3)
GROUP BY id
I have a MySQL query where I have a nested SELECT that returns an array to the parent:
SELECT ...
FROM ...
WHERE ... IN (SELECT .... etc)
I would like to store the number of returned results (row count) from the nested SELECT, but doing something like IN (SELECT count(...), columnA) does not work, as the IN expects just one result.
Is there a way to store the returned result count for later use within the parent statement?
You're probably going to have to select the results of your nested statement into a temporary table. Then you can do an IN and a count on it later. I'm more familiar with MS-SQL, but I think you should be able to do it like this:
CREATE TEMPORARY TABLE tmp_table AS
SELECT something
FROM your_table;
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
If that doesn't work, you may have to provide full details to the temporary table creation statement as you would with a normal "CREATE TABLE". See here in the MySQL manual, and here for a similar example.
CREATE TEMPORARY TABLE tmp_table
(
tableid INT,
somedata VARCHAR(50)
);
INSERT INTO tmp_table
SELECT ...
FROM ...
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
Rich
You mentioned in your comment that your query look like this:
SELECT
tabA.colA,
tabA.colB
FROM tabA
WHERE tabA.colA IN ( SELECT tabA.colA FROM tabA WHERE tabA.colB = 1 )
I might be missing something, but you don't need a subquery for this. Why don't you do it in a regular where condition:
SELECT
tabA.colA,
tabA.colB,
FROM tabA
WHERE tabA.colB = 1
You can use IN predicate for multiple columns like this:
SELECT *
FROM table
WHERE (col1, col2) IN
(
SELECT col3, col4
FROM othertable
)
If you want to select COUNT(*) along with each value, use this:
SELECT colA, colB, cnt
FROM (
SELECT COUNT(*) AS cnt
FROM tabA
WHERE colB = 1
) q,
tabA
WHERE colB = 1