SQL - Concat in where clause with IN - sql

I'm trying use IN to query multiple columns. If I use "=", I return rows (see example) but I would like to query multiple.
need query table to return rows A12345 and B98765 but not C00000
column1 | column2
A 12345
B 98765
C 00000
This works
SELECT *
FROM TABLE
WHERE (column1,column2) = ('A',12345)
This does not work.
SELECT *
FROM TABLE
WHERE (column1,column2) IN (('A',12345),('B',98765))
Here is error:
Error: SQL0104N An unexpected token "," was found following ",". Expected tokens may include: "AT MICROSECONDS MICROSECOND SECONDS SECOND MINUTES MINUTE HOURS". SQLSTATE=42601
(State:42601, Native Code: FFFFFF98)
I've tried several variations of parenthesis, commas's, etc and can't get it to work. Is it possible to do this and if so can you provide the syntax.
thanks

DB2 9.7 onwards:
SELECT *
FROM TABLE
WHERE (column1, column2) IN (VALUES ('A', 12345), ('B', 98765))
One solution is to use a temp table:
create table #tmp
(
col1 varchar(2),
col2 int
);
insert into #tmp (col1, col2)
values ('A', 12345), ('B', 98765)
SELECT t.* FROM TABLE t
JOIN #tmp ON #tmp.col1 = t.column1 and #tmp.col2 = t.column2
You haven't stated your RDBMS, but have you tried:
SELECT * FROM TABLE
WHERE (column1, column2) IN ('A', 12345)
OR (column1, column2) IN ('B', 98765)

Depending on your data, this might be workable:
SELECT *
FROM TABLE T
JOIN (
SELECT 'A' COL1, 12345 COL2
UNION ALL
SELECT 'B', 98765
UNION ALL
SELECT 'C', 44365) AS Matches
ON T.column1 = Matches.COL1
AND T.column2 = Matches.COL2

This turned out to be easy and should have known this.
SELECT *
FROM TABLE
WHERE CONCAT(column1, column2) IN ('A12345','B98765')

Related

Insert multiple rows in a single query using results of a select statement

I am looking for a compact way to do this - insert multiple rows into a table with values from multiple columns of a row from another table. My destination table is really a list with a single column:
declare #stringList table
(
val nvarchar(100)
)
This is how we can insert multiple rows:
INSERT INTO #stringList ( val ) VALUES
Val1, Val2, Val3, ...
This is how we insert from a select:
INSERT INTO #stringList
SELECT col1 FROM table1 where id=something
But I cannot seem to find a way to use both at the same time.
I can select from one column:
insert into #stringList (val)
select col1 from table1 where id=something
But it doesn't extend to multiple columns:
insert into #stringList (val)
select col1, col2 from table1 where id=something
--The select list for the INSERT statement contains more items than the insert list. The number of SELECT values must match the number of INSERT columns.
I have tried various ways including using parentheses, but the syntax is not accepted:
insert into #stringList (val)
(select col1 from table1 where id=something,
select col2 from table1 where id=something
Any idea if what I want is doable?
You can unpivot using cross apply:
insert into #stringList (val)
select v.col
from table1 t1 cross apply
(values (t1.col1), (t1.col2)) v(col)
where t1.id = something;

SQL Server : How to make a Insert Into with Condition

How is the syntax to make inserts with conditions? For example: verify if the value I want to insert isn't already in the table? (considering that the column could be null)
Your description is very brief but it sounds like you want the MERGE statement.
http://technet.microsoft.com/en-us/library/bb510625.aspx
Which can be used to insert/update/delete based on if data exists or not all in one statement.
Supposing values you want to insert are variables.
You can use IF NOT EXISTS:
IF NOT EXISTS (SELECT * FROM Table1 WHERE Col1 = #Val1 AND Col2 = #Val2)
INSERT INTO Table1 (Col1, COl2) VALUES (#Val1, #Val2)
or you can use SELECT..WHERE with EXISTS
INSERT INTO Table1 (Col1, COl2)
SELECT #Val1, #Val2
WHERE NOT EXISTS (SELECT * FROM Table1 WHERE Col1 = #Val1 AND Col2 = #Val2)
or probably few more methods (NOT IN, LEFT JOIN, MERGE...)
You could use a left or right join e.g.
WITH SourceTable AS
(
SELECT
*
FROM ( VALUES
('A', 1)
,('A', 2)
,('B', 1)
,('C', 10)) nTable(nCol1, nCol2)
)
SELECT
*
INTO #SourceTable
FROM SourceTable;
WITH NewRows AS
(
SELECT
*
FROM ( VALUES
('A', 2)
,('A', 3)
,('B', 1)
,('C', 11)) nTable(nCol1, nCol2)
)
INSERT #SourceTable
(nCol1
,nCol2)
SELECT
n.nCol1
,n.nCol2
FROM #SourceTable s
RIGHT JOIN NewRows n
ON s.nCol1=n.nCol1
AND s.nCol2=n.nCol2
WHERE s.nCol1 IS NULL;
Do you mean something like this?
insert into t(col)
select 'value'
where not exists (select 1 from t where col = 'value');
However, I would recommend that you use a unique index, filtered index, or foreign key constraint to maintain data integrity.
Try this:
insert into target_table (col1, col2, ...)
select col1, col2, ...
from source_table
where col_x not in (
select col_y from target_tabke where col_y is not null)
or (col_x is null and not exists (
select * from target_table where col_y is null))

INSERT INTO subtract 2 values

Is it possible for an INSERT query to subtract 2 values you have entered to create a 3rd value that can then be inserted into a table - if that makes sense...
e.g.
INSERT INTO table1 (column1, column2, column3)
VALUES ('50', '25', column1 - column2)
INSERT INTO table1 (column1, column2, column3)
(select ('50', '25', column1 - column2) from table1 where conditions)
This is a sample query! hope it helps!
Convoluted:
INSERT INTO table1 (column1,column2,column3)
select column1,column2,column1-column2
from
(select 50 as column1,
25 as column2
) t
Since you can't reference other columns from the same SELECT clause, you have to do it as a subquery. I've also switched to using int literals rather than strings, because I can't make subtraction make sense in my head otherwise.
You could also do it using a Table Value Constructor:
INSERT INTO table1 (column1,column2,column3)
select column1,column2,column1-column2
from
( VALUES (50, 25)
) AS t (column1, column2);
As indicated in my comment though, if the relationship should always hold, I'd build table1 as:
CREATE TABLE table1 (
column1 int not null,
column2 int not null,
column3 as column1 - column2
--More columns
)
Because that way, the column3 value is always correct.
You can create function that subtracts values and use this function in insert. This is the right way to do such things:
INSERT INTO table1 (column1, column2, column3)
(select ('50', '25', your_function() ) from table1 where conditions)
/
Using the "INSERT INTO" would do this:
INSERT INTO Table1Name (column1, column2, column3,)
(select 'X', 'Y', X - Y as Z)
Here is a link to SQL Authority with more examples of INSERT INTO
Another method would to be add a trigger to the table, where on insert of data, the third column would be updated with the difference of the first two columns.

SQL query construction issue

There two tables:
Table1
field1 | field2
Table2
field1
“string1”
“string2”
I need to insert concatenation of table2.field1 values into table1, so it looks like
insert into table1(field1, field2) values (1, “string1string2”);
How can I do it? Is there any SQL-standard way to do it?
PS: string1 and string2 are values of the field1 column.
PPS: the main subtask of my question is, how can I get the result of select query into one row? All examples I've seen just use concatenation, but in all your examples SELECT subquery does not return string concatenation for all values of the table2.field1 column.
There is no ANSI standard SQL way to do this.
But in MySQL you can use GROUP_CONCAT
insert into table1 ( field1, field2 )
select 1, group_concat(field1) from table2
In SQL Server 2005 and later you can use XML PATH,
insert into table1 ( field1, field2 )
select 1, (select field1 from table2
for xml path(''), type).value('.','nvarchar(max)')
In Oracle, you can refer to Stack Overflow question How can I combine multiple rows into a comma-delimited list in Oracle?.
INSERT INTO TABLE1 (FIELD1, FILED2) VALUES (1, CONCAT("string1", "string2"))
try this :
insert into table1(field1, field2)
select table2.field1, table2.string1 || table2.string2 from table2;
You can add a where clause to the query to select only some entries from table2 :
insert into table1(field1, field2)
select table2.field1, table2.string1 || table2.string2 from table2
where table2.field = 'whatever';
I'd try with
insert table1 select field1, string1+string2 from table2
tested with MSSQL Server 2008
create table #t1 (n int, s varchar(200))
create table #t2 (n int, s1 varchar(100), s2 varchar(100))
insert #t2 values (1, 'one', 'two') -- worked without into ???
insert #t2 values (2, 'three', 'four') -- worked without into ???
insert #t1 select n, s1+s2 from #t2 -- worked without into ???
select * from #t1
drop table #t1
drop table #t2
After the edit:
No, if you have no way to identify the lines in table2 and sort them the way you want it is impossible. Remember that, in the absence of a order by in the SQL statement, lines can be returned in any order whatsoever
Assuming this is SQL server,
Insert into table1 (field1, field2)
select field1, string1 + string2
from table2
In oracle you will do it as -
Insert into table1 (field1, field2)
select field1, string1 || string2
from table2

inserting multiple rows with one insert command

Is it possible to insert more than one row in a table with one insert statement?
I know this will happen if I do:
insert into table ( fields ) select values from another_table
But what if I want to insert:
row 1 - ( a1, b1, c1 )
row 2 - ( a2, b2, c2 )
...
row n - ( an, bn, cn )
with just one insert command?
Two solutions (source : http://appsfr.free.fr/spip.php?article21 ):
INSERT ALL
INTO table (column1, column2)
VALUES (value1, value2)
INTO table (column1, column2)
VALUES (value1, value2)
...etc...
SELECT * FROM DUAL ;
or
INSERT INTO table (column1, column2)
SELECT value1, value2 FROM DUAL UNION ALL
SELECT value1, value2 FROM DUAL UNION ALL
...etc...
SELECT value1, value2 FROM DUAL ;
Insert All
INSERT ALL
INTO mytable (column1, column2, column3) VALUES ('val1.1', 'val1.2', 'val1.3')
INTO mytable (column1, column2, column3) VALUES ('val2.1', 'val2.2', 'val2.3')
INTO mytable (column1, column2, column3) VALUES ('val3.1', 'val3.2', 'val3.3')
SELECT * FROM dual;
INSERT INTO products (product_no, name, price) VALUES
(1, 'Cheese', 9.99),
(2, 'Bread', 1.99),
(3, 'Milk', 2.99);
INSERT INTO College (CustomerID, FirstName, MiddleName, LastName)
SELECT 7, N'Charles', N'Simmons', N'Burns'
UNION ALL
SELECT 9, N'Dominic', N'Fred', N'Einsten'
UNION ALL
SELECT 12, N'Dave', N'William, N'Bryan';
NOTE:
Letter N before each hard coded string value converts string to an NVARCHAR value to match the datatype of the column.
No, this is not possible. As you already stated yourself, it is only possible with a select clause providing the insert values and rows.