Here's my questions in writing some scripts in MySQL:
I get a table T1 with some columns called id, t1_col_01, t1_col_02, and a table T2 with some columns called id, t2_col_01, t2_col_02.
For each row R1 in T1, I want to update R1.t1_col_01 = 'Yes' if the there are multiple rows in T2 that has the same id column with R1.id. If not, set R1.t1_col_01 = 'No'.
I tried to write:
update T1, T2
set
T1.t1_col_01 = 'Yes'
where
(select count(*) from T2 where T2.id = T1.id) > 1
But it didn't work.
What you need is this:
update T1
inner join T2
on ( T2.id = T1.id )
set T1.t1_col_01 = 'Yes'
where (select count(*) from T2 where T2.id = T1.id) > 1
See it here on fiddle:
http://sqlfiddle.com/#!2/0edc4/1
Related
I had a problem creating a MySQL query with a subquery.
I wanted to use some data from the main query on the subquery, as many times did.
But this time I wanted to use it in a JOIN and didn't worked. I really want to understand why this happens.
I will show you some examples that works and the one that didn't.
I made this simple structure to reproduce the example:
# table1
id field1
1 *first_value*
2 *another_value*
#table2
id field2
1 *second_value*
Using table1.id on the WHERE of the subquery to get a value, the most typical use for me (I know this can be a join, but i try to show the difference):
SELECT
t1.field1,
(
select t2.field2
FROM table2 as t2
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
You can use table1.id on the SELECT part too (not much sense in the example, but works):
SELECT
t1.field1,
(
select t1.id as field2
FROM table2 as t2
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
Now, if you try to use it on a JOIN inside the subquery, then, crashes:
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = t1.id
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
Kernel error: Error( 1054 ) 42S22: "Unknown column 't1.id' in 'on clause'"
Buuut, u can do the JOIN using the field in another subquery changing ON t3.id = t1.id to ON t3.id = (SELECT t1.id) ???
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = (SELECT t1.id)
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1'
I wonder to know why the third example query doesn't work while all others does.
Can someone explain this, please?
Thank you :)
That's because all elements in the ON clause of a JOIN, must belong the one of the joined tables, so as your t2.id must be equal to t1.id, you can do
SELECT
t1.field1,
(
select t1.id
FROM table2 as t2
LEFT JOIN table1 as t3 ON t3.id = t2.id
WHERE t2.id = t1.id
) as field2
FROM table1 as t1
WHERE t1.id = '1';
Can you help me with mysql query ? I would like to empty all duplicated product name and keep ONLY one row (product name and its SKU).
I wrote the query like this. Can you please confirm If it's the right syntax
UPDATE tvcom_product t1 JOIN
(SELECT name
FROM tvcom_product
GROUP BY name
HAVING count(product_id) > 1) dup ON t1.name = dup.name
SET t1.name = '' WHERE t1.sku != ''
UPDATE tvcom_product t1
JOIN tvcom_product t2 ON t2.name = t1.name AND t2.sku < t1.sku
SET t1.name = ''
This will reset name for all the records which have duplicates with same name. It will leave just one record with the smallest (alphabetically) SKU.
Instead of t2.sku < t1.sku you can write t2.id < t1.id - should be more optimal, it will leave out the record with smallest ID.
Upd. This is simplest but not most optimal way. For huge tables this one should work better:
UPDATE tvcom_product t1
JOIN (
SELECT name, MIN(id) id
FROM tvcom_product
GROUP BY name
HAVING COUNT(*) > 1
) t2 ON t1.name = t2.name AND t1.id != t2.id
SET t1.name = ''
If you want to optimise it even more then you should store the sub-query in a separate table and join it. Of course id in this query can be changed with sku.
I thought I will get answer for this query straight away but I didn't find any Q&A which was exactly what I am looking for.
So, I have two tables.
Table 1: id,c_id,created_at
Table 2:id,c_id,b_date,s_type
I want a query which gives output corresponds to each row in table 1. The output should be the latest b_date in table 2 prior to created_at in Table 1 and the s_type corresponding to the latest b_date. The linking condition between Table 1 and Table 2 isc_id. Both the tables have multiple rows containing same c_id.
My table 1,table 2 and output will look like this.
I am not allowed to embed images as of now. So please click to see the images.
Possibly this
SELECT T1.ID,T1.C_ID,T1.CREATED_AT,T2.B_DATE,T2.S_TYPE
FROM TABLE1 T1
JOIN TABLE2 T2 ON T1.C_ID = T2.C_ID
WHERE T2.B_DATE = (SELECT MAX(T3.B_DATE) FROM TABLE2 T3 WHERE T3.b_DATE < T1.CREATED_AT AND T3.C_ID = T1.C_ID)
;
or maybe this
SELECT S.ID,S.C_ID,S.CREATED_AT,S.B_DATE,T.S_TYPE
FROM
(
SELECT T1.ID,T1.C_ID,T1.CREATED_AT,T2.B_DATE,T2.S_TYPE
FROM TABLE1 T1
JOIN TABLE2 T2 ON T1.C_ID = T2.C_ID
WHERE T2.B_DATE = (SELECT MAX(T3.B_DATE) FROM TABLE2 T3 WHERE T3.b_DATE < T1.CREATED_AT AND T3.C_ID = T1.C_ID)
) S
JOIN
(SELECT T1.ID,T1.C_ID,T1.CREATED_AT,T2.B_DATE,T2.S_TYPE
FROM TABLE1 T1
JOIN TABLE2 T2 ON T1.C_ID = T2.C_ID
WHERE T2.B_DATE = (SELECT MAX(T3.B_DATE) FROM TABLE2 T3 WHERE T3.C_ID = T1.C_ID)
) T ON S.C_ID = T.C_ID
;
I want to update one table which is inner join to another table, but the rows which should be updated should have specific condition or not exist in the second table:
Update T1
Set STATUS = 'R'
From table1 T1
inner join table2 T2
on T1.ID = T2.ID and T2.STATUS = 'F'
Update T1
Set STATUS = 'R'
From table1 T1
Where T1.ID not exists in(Select T2.ID from table2 T2)
How can I write it by one Query?
You can do an OR in the where clause. Like the following :
Update T1 Set STATUS = 'R' From table1 T1
inner join table2 T2 on T1.ID = T2.ID and T2.STATUS = 'F' or T1.ID not exists in(Select T2.ID from table2 T2)
I have the 2 following tables t1, t2 with values,
t1 t2
1 4
2 2
3 3
Now I want to output
1
4
How can I get this output in select query ?
This will get you each item from t1 that is not present in t2, and each item in t2 that is not present in t1:
select t1.id from t1
left join t2 on t2.id = t1.id
where t2.id is null
union all
select t2.id from t2
left join t1 on t1.id = t2.id
where t1.id is null
(I have assumed that the field name in each table is named id just for the sake of being able to write a query against the tables.)
Another way would be:
select coalesce(t1.id, t2.id)
from t1
full outer join t2 on t2.id = t1.id
where t1.id is null or t2.id is null
Another way. Just COUNT them.
This works if the values are unique per table
SELECT
CombinedValue
FROM
(
SELECT t1 AS CombinedValue FROM t1
UNION ALL
SELECT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
If not unique per table
SELECT
CombinedValue
FROM
(
SELECT DISTINCT t1 AS CombinedValue FROM t1
UNION ALL
SELECT DISTINCT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
you can use Joins in MySql to proceed and to obtain result.
this will help you
http://www.techrepublic.com/article/sql-basics-query-multiple-tables/1050307