INSERT INTO using WHERE - sql-server-2008

I'm trying to insert the JobNo and CellNo columns that are not in Table_1 from View_1. I wrote this query & I get an error.
Please help me out in correcting this.
I'm using SQL Server 2008
INSERT INTO Table_1(ID, JobNo, CellNo)
SELECT View_1.ID, View_1.JobNo, View_1.CellNo
FROM View_1
WHERE View_1.JobNo
AND View_1.CellNo NOT IN (SELECT JobNo, CellNo FROM Table_1)

The issue is your WHERE clause - you can't compare sets of fields like this. You can only compare a single field at a time.
Try instead:
WHERE View_1.JobNo NOT IN(SELECT JobNo FROM Table_1)
AND View_1.CellNo NOT IN (SELECT CellNo FROM Table_1)
Alternatively you can use a single EXISTS statement:
INSERT INTO Table_1(ID, JobNo, CellNo)
SELECT View_1.ID, View_1.JobNo, View_1.CellNo
FROM View_1 v
WHERE NOT EXISTS (SELECT 1 FROM Table_1 t
WHERE t.JobNo = v.JobNo
AND t.CellNo = v.CellNo)

Since you're using SQL Server 2008, you can make use of the MERGE statement:
MERGE INTO Table_1 dst
USING (
SELECT View_1.ID, View_1.JobNo, View_1.CellNo
FROM View_1
) src
ON src.JobNo = dst.JobNo
AND src.CellNo = dst.CellNo
WHEN NOT MACHED THEN INSERT (ID, JobNo, CellNo)
VALUES (src.ID, src.JobNo, src.CellNo)
I personally find a MERGE statement more concise than INSERT .. SELECT .. WHERE.

Related

SQL Query to find MAX values based upon count and some filters

Table looks like below :
/* Create a table called test */
CREATE TABLE test(Id integer PRIMARY KEY,Col_Key text, Ng text, node text);
/* Create few records in this table */
INSERT INTO test VALUES(1,'key1','g1','n2');
INSERT INTO test VALUES(2,'key1','g2','n3');
INSERT INTO test VALUES(3,'key2','g3','n1');
INSERT INTO test VALUES(4,'key2','g4','n1');
INSERT INTO test VALUES(5,'key3','g5','n1');
INSERT INTO test VALUES(6,'key3','g6','n2');
INSERT INTO test VALUES(7,'key4','g7','n1');
INSERT INTO test VALUES(8,'key4','g8','n1');
INSERT INTO test VALUES(9,'key5','g8','n4');
INSERT INTO test VALUES(10,'key5','g9','n4');
INSERT INTO test VALUES(11,'key6','g10','n4');
INSERT INTO test VALUES(12,'key6','g11','n4');
INSERT INTO test VALUES(13,'key7','g11','n4');
INSERT INTO test VALUES(14,'key9','q11','n3');
INSERT INTO test VALUES(15,'key9','q11','n2');
INSERT INTO test VALUES(16,'key10','q12','n1');
COMMIT;
I'm trying to get values from the node column which have a maximum count and whose Ng value starts with g.
I have done something like this:
SELECT TEMP.node,COUNT(TEMP.node) FROM (SELECT Col_Key,Ng,node
from test WHERE (Ng LIKE 'g%')) TEMP GROUP BY TEMP.node;
which gives below result:
But, in the result I want only n4 and n1 in result (only node column not count) as they have the maximum count. I am unable to add this part in my query. Please help.
Above data is just a small piece of data but i will have thousands of rows in my SQL table, so my query should be efficient.
PS :- I tried doing below :
SELECT TEMP2.node,TEMP2.CNT FROM (SELECT TEMP.node,COUNT(TEMP.node) AS CNT FROM (SELECT Col_Key,Ng,node
from test WHERE (Ng LIKE 'g%')) TEMP GROUP BY TEMP.node) TEMP2 WHERE TEMP2.CNT = (SELECT MAX(TEMP2.CNT) FROM TEMP2);
but last part of the query with where clause is wrong as it is unable to find table TEMP2.
but this WHERE cluase kinds of give idea what i want exaclty.
RESULT should be :
node
n1
n4
How about something like:
SELECT
t.node,
COUNT(*)
FROM
test t
WHERE
t.Ng like 'g%'
GROUP BY
t.node
HAVING
COUNT(*) = (
SELECT
MAX(a.count_of_nodes)
FROM
(
SELECT
node,
COUNT(*) AS count_of_nodes
FROM
test
WHERE
Ng like 'g%'
GROUP BY
node
) a
)
;
Good luck!
You don't need a subquery for your query:
select node, count(*)
from test
where Ng LIKE 'g%'
group by node;
Getting one maximum is easy (using limit), but you want all of them. One method uses a subquery and a having clause:
select node, count(*)
from test
where Ng LIKE 'g%'
group by node
having count(*) = (select count(*)
from test t2
where t2.Ng LIKE 'g%'
group by t2.node
order by count(*) desc
limit 1
);
This is more complicated than it needs to be because MySQL (pre-8.0) supports neither window functions nor CTEs. Happily, the syntax is simpler in MySQL 8+.
You can use a temptable to handle this situation easily and readable like below:
CREATE TEMPORARY TABLE temptable AS (
SELECT TEMP.node,COUNT(TEMP.node) as cnt FROM (SELECT Col_Key,Ng,node
from test WHERE (Ng LIKE 'g%')) TEMP GROUP BY TEMP.node
)
select node, cnt
from temptable t
where cnt = (select max(cnt) from temptable)
See: http://www.sqlfiddle.com/#!9/e749de/1/0

Create a table from max and min values in another

I have table with Name|ValueA|ValueB.1|ValueB,2 where Name is not unique.
I want to extract the B.1 and B.2 values for the low and high A vales for each name.
Bob|1|200|205
Bob|2|500|625
Bob|7|450|850
Bob|3|644|125|
Ann|4|120|120
Ann|8|451|191
Ann|9|145|982
I want a new table with unique names with high and low ValueA, ValueB.1, ValueB.2
Bob|1|7|200|450|205|850
Ann|4|9|120|145|120|982
I remember there is some way to use min/max but am not sure how to set up the query to extract the new table.
INSERT newtable (Name, ValueA, ValueB.1, ValueB.2)
SELECT Name,MAX(ValueA),MIN(ValueA),MAX(ValueB.1),MIN(Value B.1),
MAX(ValueB.2),MIN(ValueB.2)
FROM oldtable GROUP BY Name
Should do the trick.
Assuming that values of A are distinct (at least within a name):
INSERT
INTO newtable
SELECT name, mmin.a, mmax.a, mmin.b1, mmin.b2, mmax.b1, mmax.b2
FROM (
SELECT name, MIN(a) mina, MAX(a) maxa
FROM mytable
GROUP BY
name
) md
JOIN mytable mmin
ON (mmin.name, mmin.a) = (md.name, md.mina)
JOIN mytable mmax
ON (mmin.name, mmin.a) = (md.name, md.maxa)

MySQL insert into table with a set of values

I need to insert a table with some values (eg: 'NDA' in this case). This seems to work well if I have just one value to be inserted. I have around a dozen of similar values, is there a was i can tweak this query to insert say { 'NDA', 'SDM', 'APM' } values. Was curious to know if it can be done without a stored procedure or copy pasting the same statements over and changing the values.
INSERT IGNORE INTO customer_feature (customer_id, feature)
SELECT c.id, 'NDA' FROM
customer as c
where c.edition = 'FREE_TRIAL';
Reference: mysql -> insert into tbl (select from another table) and some default values
Is this what you want?
INSERT IGNORE INTO customer_feature(customer_id, feature)
select c.id, f.feature
from customer c cross join
(select 'NDA' as feature union all select 'SDM' union all select 'APM'
) f
where c.edition = 'FREE_TRIAL';

INSERT SELECT with condition

I'm trying to do a INSERT SELECT with condition but smthg seems to be wrong. I get an 1064 error for wrong syntax.
Here is the query :
INSERT INTO `db1`.`table`.`field` (
SELECT a.`field1` , a.`field2`
FROM `db2`.`table1` a, `db2`.`table2` b
WHERE a.`field1` = b.`field1`
AND b.`field2` = 'value'
)
WHERE a.`field1` = `db1`.`table1`.`field1`
Thank in advance for any suggestions
Syntax for the insert select is :
INSERT california_authors (au_id, au_lname, au_fname)
SELECT au_id, au_lname, au_fname
FROM authors
WHERE State = 'CA'
so in you case it like
INSERT INTO `db1`.`table` (.... field list ...)
select
... col for select .....
from table
where ... where condition ....
The syntax for INSERT INTO is usually
INSERT INTO myTable (field1,field2,...,fieldN)
SELECT field1,field2,etc FROM myTable WHERE condition
You need to simplify your queries and think through what you're trying to do.
My question was bad. In this case it is not Insert but an Update query which is needed

MySql UNION for UPDATE

Is there a way to update multiple rows with different values for each row using a single SQL query? I have to update one colum in many rows with different data. Using individual update queries for each row seems excessive so if it's possible I would like to consolidate this process into a single SQL statement or at least reduce the number of queries required.
I am using PHP with the Zend framework and MySql.
Create a temporary table and fill it with:
CREATE TEMPORARY TABLE temptable (id INTEGER, VALUE VARCHAR(200))
INSERT
INTO temptable
VALUES
('1', 'val1'),
('2', 'val2'),
('3', 'val3'),
('4', 'val4')
Then issue:
UPDATE
mytable m, temptable t
SET m.value = t.value
WHERE m.id = t.id
Don't know about MySQL specifically, but to update multiple rows based on a SELECT, or a UNION of multiple SELECTs, I would do
UPDATE U
SET MyColumn = T.OtherColumn
FROM MyUpdateTable AS U
JOIN
(
SELECT [OtherColumn] = OtherColumn1
FROM MyOtherTable1
WHERE ...
UNION
SELECT OtherColumn2
FROM MyOtherTable2
WHERE ...
) AS T
ON T.ID = U.ID
Update 10/28/2014, converted to work for MySQL:
UPDATE MyUpdateTable AS U
JOIN
(
SELECT [OtherColumn] = OtherColumn1
FROM MyOtherTable1
WHERE ...
UNION
SELECT OtherColumn2
FROM MyOtherTable2
WHERE ...
) AS T
ON T.ID = U.ID
SET MyColumn = T.OtherColumn
I know this works for SQL Server, so it's worth a try in MySQL.
update xtable
set a =
Case
when a = "a"
then z
when a = "b"
then y
End
where ...
You can construct the case statement based on your different rows.