how to use multiple insert in sql navigator - sql

i am new to sql and i am trying to make a simple to use insert for every day use,
i have a table(matrix) that holds the connection between 3 variables ,
in most cases i have to insert or update the matrix but each insert is multiplied because of the matrix, i have made a simple example :
SELECT * FROM table_name
where col1='A'
and col2 in ('1G','2F','3Q')
and col3 ='B'
/
INSERT INTO table_name VALUES('A','1G','B');
INSERT INTO table_name VALUES('A','2F','B');
INSERT INTO table_name VALUES('A','3Q','B');
the output table will be
A 1G B
A 2F B
A 3Q B
and in the more complex cases
SELECT * FROM table_name
where col1='A'
and col2 in ('1G','2F','3Q')
and col3 in ('B','C')
/
INSERT INTO table_name VALUES('A','1G','B');
INSERT INTO table_name VALUES('A','2F','B');
INSERT INTO table_name VALUES('A','3Q','B');
INSERT INTO table_name VALUES('A','1G','C');
INSERT INTO table_name VALUES('A','2F','C');
INSERT INTO table_name VALUES('A','3Q','C');
the output table will be
A 1G B
A 2F B
A 3Q B
A 1G C
A 2F C
A 3Q C
is there a way to make an insert that will look like this or have similar functionality
for example A :
INSERT INTO table_name VALUES('A',in ('1G',2F','3Q'),'B');
and for example b :
INSERT INTO table_name VALUES('A',in ('1G',2F','3Q'),in ('B','C'));
i usually use about 100 new values at a time in each column that is multiplied because of the matrix

You can combine a select and an insert statement. For example:
INSERT INTO table_name (col1, col2, col3)
SELECT col1, col2, col3
FROM table_x
WHERE col1='A'
AND col2 in ('1G','2F','3Q')
AND col3 ='B'
To do that table_x will need to contain all of the values that you want. If you are asking for a way to write an insert statement that builds a 'table' of values in line using constants then no you can't do that.

Related

How to do a select insert statement in sql with a changing value in the column for each row

Basically what I am trying to do in sql is find a way to do a select insert statement where all of the values in the other columns will stay the same but one of the columns value will increase by 1 for every row that is created. I am wondering if there is a way to do that in SQL.
You can use:
INSERT INTO table_name (col1, col2, col3)
SELECT col1, col2, col3 + 1
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (col1, col2, col3) AS
SELECT LEVEL, LEVEL, LEVEL FROM DUAL CONNECT BY LEVEL <= 3;
Then, after the INSERT, the table contains:
COL1
COL2
COL3
1
1
1
2
2
2
3
3
3
1
1
2
2
2
3
3
3
4
And the col1 and col2 values of the inserted rows are the same and the col3 values have been incremented by 1.
If you want to increment the values by the number of rows being inserted then you can use:
INSERT INTO table_name (col1, col2, col3)
SELECT col1, col2, col3 + COUNT(*) OVER ()
FROM table_name
However
If you are attempting to add multiple rows and keep col3 with unique values then you should not use that method and should use a sequence.
If you have the table:
CREATE TABLE table_name (col1, col2, col3) AS
SELECT LEVEL, LEVEL, table_name__col3__seq.NEXTVAL FROM DUAL CONNECT BY LEVEL <= 3;
Then you can insert the rows using:
INSERT INTO table_name (col1, col2, col3)
SELECT col1, col2, table_name__col3__seq.NEXTVAL
FROM table_name
and col3 will be populated using the next sequence values.
db<>fiddle here

SQL: Multiple Column in a Table has same a condition: WHERE COL1 LIKE 'VALUE' OR COL2 LIKE 'VALUE'

I have a problem when filtering data in a table.
SELECT *
FROM TABLE_NAME
WHERE COL1 LIKE '%VALUE%'
OR COL2 LIKE '%VALUE%'
OR COL3 LIKE '%VALUE%'...;
I want to optimize this SQL statement.
I was thinking about using WHERE IN ... but IN just filters that thing exactly equal to "VALUE".
Any idea for this?
Thanks a lot.
I tried
SELECT *
FROM TABLE_NAME
WHERE 'VALUE' IN (COL1, COL2);
but I expected
SELECT *
FROM TABLE_NAME
WHERE '%VALUE%' LIKE/IN (COL1,COL2);
Can I do that in PostgreSQL?
To answer your direct question, you could concatenate the columns and use an array if there's multiple values you want to search for.
create table t1 (
col1 text
,col2 text
,col3 text
);
insert into t1 (col1,col2,col3)
values
('foobar', 'bar', 'alpaca')
,('cat','dog','duck');
SELECT
*
FROM t1
WHERE (col1 ||' '|| col2 ||' '|| col3) ILIKE ANY(ARRAY['%foo%','%bar%', '%cat%'])
https://dbfiddle.uk/?rdbms=postgres_14&fiddle=e54e5eecbdc4c1374d441d6553049fbf
Unsure how performant this would be, but I believe it answers your direct question and is probably more readable than a long list of OR statements.

How to know the column name from a table based on the column values

I am working in Informix and I want to know if there is a simple way to know the tabname/colname by its possible column values.
For example:
table1
Register 1
==========
id 1
col1 3
col2 Y
Register 2
==========
id 2
col1 43
col2 X
Register 3
==========
id 2
col1 0
col2 Z
Register 4
==========
id 2
col1 23
col2 F
table2
Register 1
==========
id 1
col1 X
col2 Y
Register 2
==========
id 2
col1 X
col2 X
Register 3
==========
id 2
col1 Z
col2 Z
Register 4
==========
id 2
col1 X
col2 X
table3
Register 1
==========
id 1
col1 ASX
With this database, if I want to know the colnames and their related tabnames of the database that contain X, Y and Z (amoung other values).
It could be something like this:
select tabname, colname
where ('X','Y','Z') in colnamevalues --this has been invented by me
And this should return the following values:
table1.col2
table2.col1
table2.col2
--Note that the columns fetched contains also other values
--different from 'X', 'Y' and 'Z' but T didn't fix in this case
--the whole list of values, only some of them
I have queried for other Q&A but all of them look to use some functions of other databases such as Oracle or SQL Server and I don't understand them very well.
You can get all the tables that exist on a database by querying the systables:
SELECT tabname
FROM systables
WHERE tabtype = 'T' --get only tables
AND tabid > 99; --skip catalog tables
You can join it to the syscolumns table to get the columns:
SELECT t.tabname, c.colname
FROM systables t
INNER JOIN syscolumns c ON (c.tabid = t.tabid)
WHERE t.tabtype = 'T' AND t.tabid > 99;
And if you know the type of values you can even filter it. Example if you're looking for "strings":
SELECT t.tabname, c.colname
FROM systables t
INNER JOIN syscolumns c ON (c.tabid = t.tabid)
WHERE t.tabtype = 'T' AND t.tabid > 99
AND MOD(c.coltype,256) IN (
0, --CHAR
13, --VARCHAR
15, --NCHAR
16, --NVARCHAR
40, --LVARCHAR
43 --LVARCHAR
);
The next example works, but it really should be optimized and bullet proof, but can get you kick off.
When I have time I get another look at it and check what can be optimized and put some error handling.
Another way to do it is scripting, what OS are you running?
Schema creation:
CREATE TABLE tab1(
id INT,
col1 CHAR(3),
col2 CHAR(3)
);
INSERT INTO tab1 VALUES (1, 3, 'Y');
INSERT INTO tab1 VALUES (2, 43, 'X');
INSERT INTO tab1 VALUES (2, 0, 'Z');
INSERT INTO tab1 VALUES (2, 23, 'F');
CREATE TABLE tab2(
id INT,
col1 CHAR(3),
col2 CHAR(3)
);
INSERT INTO tab2 VALUES (1, 'X', 'Y');
INSERT INTO tab2 VALUES (2, 'X', 'X');
INSERT INTO tab2 VALUES (2, 'Z', 'Z');
INSERT INTO tab2 VALUES (2, 'X', 'X');
CREATE TABLE tab3(
id INT,
col1 CHAR(3)
);
INSERT INTO tab3 VALUES (1, 'ASX');
Sample function:
CREATE FUNCTION get_columns()
RETURNING LVARCHAR(257) AS col;
DEFINE stmt VARCHAR(255);
DEFINE tab_name VARCHAR(128,0);
DEFINE tab_id INTEGER;
DEFINE col_name VARCHAR(128,0);
DEFINE o_tname VARCHAR(128,0);
DEFINE o_cname VARCHAR(128,0);
CREATE TEMP TABLE out_table(
t_name VARCHAR(128,0),
c_name VARCHAR(128,0)
);
CREATE TEMP TABLE tab_v (
col1 VARCHAR(255)
);
INSERT INTO tab_v VALUES ('X');
INSERT INTO tab_v VALUES ('Y');
INSERT INTO tab_v VALUES ('Z');
FOREACH tables FOR
SELECT tabname, tabid
INTO tab_name, tab_id
FROM systables
WHERE tabid > 99 AND tabtype = 'T'
FOREACH column FOR
SELECT colname
INTO col_name
FROM syscolumns
WHERE tabid = tab_id
AND MOD(coltype,256) IN (
0, --CHAR
13, --VARCHAR
15, --NCHAR
16, --NVARCHAR
40, --LVARCHAR
43 --LVARCHAR
)
LET stmt = "INSERT INTO out_table "||
"SELECT '"||tab_name||"', '"||col_name||"' "||
"FROM "||tab_name||" "||
"WHERE EXISTS (SELECT 1 FROM tab_v v WHERE v.col1 = "||col_name||");";
EXECUTE IMMEDIATE stmt;
END FOREACH
END FOREACH
FOREACH out FOR
SELECT UNIQUE t_name, c_name
INTO o_tname, o_cname
FROM out_table
RETURN o_tname||"."||o_cname WITH RESUME;
END FOREACH
DROP TABLE out_table;
DROP TABLE tab_v;
END FUNCTION;
EXECUTE FUNCTION get_columns();

Insert with select max fail in sql for Oracle

When use a bunch of INSERT statements as below it takes forever :
INSERT INTO my_table ( col1, col2, id_col) VALUES ('val1', 'val1', (select max(my_table_ID) from my_table)+1);
If I run one by one and commit then it works fine. What is the reason?
I know sequence should be used in production. But I am writing this to insert few rows in toad.
may be
INSERT INTO my_table ( col1, col2, id_col)
VALUES ('val1', 'val1', (select max(my_table_ID)+1 from my_table));
or in pl/sql block
declare
v_max number(10);
begin
select max(my_table_id) + 1 into v_max
from my_table;
insert into my_table ( col1, col2, id_col)
values ('val1', 'val1', v_max);
end;
/
but, i don't know you task...
may be used sequence + trigger before insert?

How to convert a column header and its value into row in sql?

I have a table with columns say col1, col2, col3. The table has many rows in it.
Let's assume val1, val2, val3 is one such row. I want to get the result as
Col1, Val1
Col2, Val2
Col3, Val3
That is 3 rows - one for each column and its value.
I am using SQL Server 2008. I read about pivots. Are pivots a way to solve this problem? Can someone route me to some examples or solutions how to solve this problem?
Thanks a lot
Maybe something like this:
Test data
DECLARE #T TABLE(Col1 INT, Col2 INT, Col3 INT)
INSERT INTO #T
VALUES (1,1,1)
Query
SELECT
*
FROM
(
SELECT
t.Col1,
t.Col2,
t.Col3
FROM
#T AS t
) AS SourceTable
UNPIVOT
(
Value FOR Col IN
(Col1,Col2,Col3)
) AS unpvt
Output
1 Col1
1 Col2
1 Col3
To do this kind of thing read the following: Using PIVOT and UNPIVOT
Pivot function allow you to convert row values in from of column..
Also check : Dynamic Pivoting in SQL Server
Example :
create table #temptable(colorname varchar(25),Hexa varchar(7),rgb varchar(1), rgbvalue tinyint)
GO
insert into #temptable values('Violet','#8B00FF','r',139);
insert into #temptable values('Violet','#8B00FF','g',0);
insert into #temptable values('Violet','#8B00FF','b',255);
insert into #temptable values('Indigo','#4B0082','r',75);
insert into #temptable values('Indigo','#4B0082','g',0);
insert into #temptable values('Indigo','#4B0082','b',130);
insert into #temptable values('Blue','#0000FF','r',0);
insert into #temptable values('Blue','#0000FF','g',0);
insert into #temptable values('Blue','#0000FF','b',255);
SELECT colorname,hexa,[r], [g], [b]
FROM
(SELECT colorname,hexa,rgb,rgbvalue
FROM #temptable) AS TableToBePivoted
PIVOT
(
sum(rgbvalue)
FOR rgb IN ([r], [g], [b])
) AS PivotedTable;
Create a temproary table:
CREATE TABLE #table2
(
name NCHAR,
bonus INT
)
Now Select and execute the below statement if there is an empty.
SELECT * FROM #table2
INSERT INTO #table2 (name,bonus) VALUES ('A',10)
INSERT INTO #table2 (name,bonus) VALUES ('B',20)
INSERT INTO #table2 (name,bonus) VALUES ('C',30)
After insert the values into table. select and execute the below line if you get records:
SELECT * FROM #table2
Input:
name bonus
A 10
B 20
C 30
Change the input into like this result
Result:
Cost A B C
Bonus 10 20 30
By using this code:
SELECT 'Bonus' AS Cost,
[A],[B],[C]
FROM
(SELECT name, Bonus
FROM #table2) AS TempTbl
PIVOT
(
AVG(bonus)
FOR [name] IN ([A],[B],[C])
) AS PivotTable;