I have a complex select query from table1 that returns 2 columns of data (id and value)
I want to update columns id and value of table2 with that data.
How can i do it ?
I have tried something like this
update table2 set (id, value) values (select ....)
and other things, but no results :P
NOTE & EDIT: I've seen about UPDATE INNER JOIN but the problem is that my select is complex ... it's like
select distinct(colA), sum(case statement....) as c1, sum(case statement...) as c2 from table2 group by colA
and colA, c1 and c2 is what i want to update in other table
thank you
Related
I have a database with 2 tables. table1 and table2.
Table1 contains a list of tests ( column 'name' ). And I want to count how many rows are missing in table2 ( this table has also a column 'name' ) according to the list of tests of table1.
So I just want to count the mismatch between table1.name and table2.name.
I tried several querys, but all didnt really work.
I tried to use the 'NOT IN' statement but it takes too much time. Like several minutes.
For example, the output should be :
COUNT(*) = 20
It means that 20 tests are missing ( or not done yet ) in table2.
I'm using MySQL, so I can't use EXCEPT or MINUS statement.
Thank you by advance.
Nordine
You can use not exists :
select count(*)
from table1 t1
where not exists (select 1 from table2 t2 where t2.name = t1.name);
If you have a duplicate name in table1 then you need count(distinct t1.name) instead.
Try the below query:
select count(case when bname is null then 1 end)
from
(
select a.name as aname, b.name as bname from
table1 a left join table2 b
on a.name=b.name)x
MINUS can be used in MySQL.
Ref:http://www.mysqltutorial.org/mysql-minus/
Try this:
SELECT name
FROM table1
MINUS
SELECT name
FROM table2
I need some help please.
I have this simple mysql query:
select '1,2,3,4,5,6' as Col1 from dual;
and the table1:
Col1
1,2,3,4,5,6
And I have another table2:
service_id service_name
1 Service1
2 Service2
I tried next query but not working:
select service_name from table2 where service_id in (select col1 from table1)
Any help would be appreciated!
Try this:
Sample data:
create table `dual` (Col1 varchar(100));
insert into `dual` values ('1,2,3,4,5,6');
create table table2 (service_id int, service_name varchar(100));
insert into table2 values
(1, 'Service1'),
(2, 'Service2');
T-SQL:
select service_name from table2 t2
where exists(
select 1 from `dual` d
where locate(concat(',', t2.service_id, ','), concat(',', d.Col1, ',')) > 0
);
I'm not sure exactly what you're trying to accomplish, but I can give you a couple hints.
Your "IN" clause would only work if your service_id was '1,2,3,4,5,6'. I can see what you're trying to do, but the database is treating the result from col1 as the whole string of numbers including all the commas, not the individual numbers themselves. If you hard-coded it as "WHERE IN (1,2,3,4,5,6)", you would be getting matches. Instead of using the "IN" clause, you could JOIN the tables and use LIKE.
Try This:
SELECT
table2.service_name
FROM
table2
LEFT OUTER JOIN
table1
ON
table1.col1 LIKE CONCAT('%', table2.service_id, '%')
WHERE
table1.col1 IS NOT NULL
I think that will do what I think you want to do.
How to:
Get values from table1.column1 (e.g. abc)
table1.column1=abc
Concatenate them with certain fixed strings, e.g.
xxx
yyy
zzz
Insert the results as separate rows in table2.column2. The final result should be rows with values like this:
table2.column2=abc_xxx
table2.column2=abc_yyy
table2.column2=abc_zzz
(table2 has a connecting column indicating to which ID the table2.column2 record corresponds in case this matters)
Repeat this process for all records in table1.column1 which have table1.item_id > 100
EDIT: For certain convenience I would like the final result rows sequence to look like:
source1_xxx
source1_yyy
source1_zzz
source2_xxx
source2_yyy
source2_zzz
and not like:
source1_xxx
source2_xxx
source1_yyy
source2_yyy
source1_zzz
source2_zzz
If I understand you correctly, you want N (e.g. 3) entries for every existing row in Table1. If so, you can CROSS JOIN Table1 to a projection of the values, like so:
INSERT INTO Table2(column2)
SELECT CONCAT(t1.column1, '_', x.col)
FROM Table1 t1
CROSS JOIN
(SELECT 'xxx' AS col
UNION
SELECT 'yyy'
UNION
SELECT 'zzz') x;
SqlFiddle here
Edit
The query was updated to be cognaisant of the ordering and filtering requirements as well:
INSERT INTO Table2(column2)
SELECT CONCAT(t1.column1, '_', x.col)
FROM Table1 t1
CROSS JOIN
(SELECT 'xxx' AS col
UNION
SELECT 'yyy'
UNION
SELECT 'zzz') x
WHERE t1.ID > 100
ORDER BY t1.column1 ASC, x.col ASC;
With an updated SqlFiddle
Modifying the answer.
Credit goes to the StuartLC ..he is right, you would need to use cross join
INSERT INTO Table2(column2)
SELECT CONCAT(t1.column1, '_', x.col)
FROM Table1 t1
CROSS JOIN
(SELECT 'xxx' AS col
UNION
SELECT 'yyy'
UNION
SELECT 'zzz') x;
is this what u want
insert into table2(column2)
select concat(col1,'_','xxx') from table1
union
select concat(1col1,'_','yyy') from table1
union
select concat(col1,'_','zzz') from table1
else keep this entire select statemnts in aview and use it in the insert statement
create view abc
as
select concat(col1,'_','xxx') from table1
union
select concat(1col1,'_','yyy') from table1
union
select concat(col1,'_','zzz') from table1
then
insert into table2(column2) select * from abc
I don't know why I am confused with this query.
I have two table: Table A with 900 records and Table B with 800 records. Both table need to contain the same data but there is some mismatch.
I need to write a mysql query to insert missing 100 records from Table A to Table B.
In the end, both Table A and Table B should be identical.
I do not want to truncate all the entries first and then do a insert from another table. So please any help is appreciated.
Thank you.
It is also possible to use LEFT OUTER JOIN for that. This will avoid subquery overhead (when system might execute subquery one time for each record of outer query) like in John Woo's answer, and will avoid doing unnecessary work overwriting already existing 800 records like in user2340435's one:
INSERT INTO b
SELECT a.* FROM a
LEFT OUTER JOIN b ON b.id = a.id
WHERE b.id IS NULL;
This will first select all rows from A and B tables including all columns from both tables, but for rows which exist in A and don't exist in B all columns for B table will be NULL.
Then it filter only such latter rows (WHERE b.id IS NULL),
and at last it inserts all these rows into B table.
I think you can use IN for this. (this is a simpliplification of your query)
INSERT INTO table2 (id, name)
SELECT id, name
FROM table1
WHERE (id,name) NOT IN
(SELECT id, name
FROM table2);
SQLFiddle Demo
AS you can see on the demonstration, table2 has only 1 records but after executing the query, 2 records were inserted on table2.
If it's mysql and the tables are identical, then this should work:
REPLACE INTO table1 SELECT * FROM table2;
This will insert the missing records into Table1
INSERT INTO Table2
(Col1, Col2....)
(
SELECT Col1, Col2,... FROM Table1
EXCEPT
SELECT Col1, Col2,... FROM Table2
)
You can then run an update query to match the records that differ.
UPDATE Table2
SET
Col1= T1.Col1,
Col2= T1.Col2,
FROM
Table T1
INNER JOIN
Table2 T2
ON
T1.Col1 = T2.Col1
Code also works when a group by and having clauses are used. Tested SQL 2012 (11.0.5058) Tab1 is source with new records, Tab 2 is the destination to be updated. Tab 2 also has an Identity column. (Yes folks, real world is not as neat and clean as the lab assignments)
INSERT INTO Tab2
SELECT a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4,-9,-9,-9,-9,MIN(hits) MinHit,MAX(hits) MaxHit,SUM(count) SumCnt, count(distinct(week)) WkCnt
FROM Tab1 a
LEFT OUTER JOIN Tab2 b ON b.t1 = a.t1 and b.t2 = a.t2 and b.t3 = a.t3 and b.t4 = a.t4 and b.val1 = a.val1 and b.val2 = a.val2 and b.val3 = a.val3 and b.val4 = a.val4
WHERE b.t1 IS NULL or b.Val1 is NULL
group by a.T1,a.T2,a.T3,a.T4,a.Val1,a.Val2,a.Val3,a.Val4 having MAX(returns)<4 and COUNT(distinct(week))>2 ;
Is there a way to write a single query to check if a set of rows matches a set of values? I have one row per set of values that I need to match and I'd like to know if all rows are matched or not. I could perform this via multiple queries such as:
select * from tableName where (value1, value2) = ('someValue1', 'someValue2')
select * from tableName where (value1, value2) = ('someOtherValue1', 'someOtherValue2')
...and so on, up to an arbitrary number of queries. How could this sort of thing be re-written as a single query where the query returns ONLY if all values are matched?
You could try something like:
select t.*
from tableName t
join (select 'someValue1' value1, 'someValue2' value2 union all
select 'someOtherValue1', 'someOtherValue2') v
on t.value1 = v.value1 and t.value2 = v.value2
where 2=
(select count(distinct concat(v1.value1, v1.value2))
from (select 'someValue1' value1, 'someValue2' value2 union all
select 'someOtherValue1', 'someOtherValue2') v1
join tableName t1
on t1.value1 = v1.value1 and t1.value2 = v1.value2)
If you have a large number of value pairs that you want to check, it may be easier to insert them into a temporary table and use the temporary table in the above query, instead of two separate hard-coded virtual tables.
What about:
SELECT *
FROM tableName
WHERE value1 IN ('someValue1', 'someOtherValue1') AND
value2 IN ('someValue2', 'someOtherValue2')
Match if exactly two records found
Select students who got q13 wrong and Q14 right
SELECT qa.StudentID FROM questionAnswer qa, Student s
WHERE qa.StudentID=s.StudentID AND
((QuestionID=13 AND Pass=0) OR (QuestionID=14 AND Pass=1))
GROUP BY qa.StudentID
HAVING COUNT(*)=2;
The Where clause matches any records where q14 is correct and q13 is incorrect
We then group by the StudentID
The having requires there to be two records