Inserting data into table with select - sql

i`m trying to do something.... I have to insert some data in to a table but..... So here is where I end up...
INSERT into HR.my_employees
(ID,LAST_NAME,FIRST_NAME,userid,SALARY)
SELECT
3 AS ID,
'Biri' AS LAST_NAME,
'Ben' AS FIRST_NAME,
substr(FIRST_NAME,1,1)||''||substr(LAST_NAME,1,7) AS userid,
1100 AS salary
FROM dual
UNION
SELECT
4 AS ID,
'Newman' AS LAST_NAME,
'Chad' AS FIRST_NAME,
substr(FIRST_NAME,1,1)||''||substr(LAST_NAME,1,7) AS userid,
750 AS salary
FROM dual;
any suggestion...

You cannot refer to an alias in the SELECT or WHERE clauses of a sub-query where it is defined. Generate the data in a sub-query (or a sub-query factoring clause) and then refer to it in an outer query:
INSERT into HR.my_employees(ID,LAST_NAME,FIRST_NAME,userid,SALARY)
WITH data (id, last_name, first_name, salary) AS (
SELECT 3, 'Biri', 'Ben', 1100 FROM DUAL UNION ALL
SELECT 4, 'Newman', 'Chad', 750 FROM DUAL
)
SELECT id,
last_name,
first_name,
SUBSTR(first_name,1,1) || SUBSTR(last_name,1,7),
salary
FROM data;
or:
INSERT into HR.my_employees(ID,LAST_NAME,FIRST_NAME,userid,SALARY)
SELECT id,
last_name,
first_name,
SUBSTR(first_name,1,1) || SUBSTR(last_name,1,7),
salary
FROM (
SELECT 3 AS id, 'Biri' AS last_name, 'Ben' AS first_name, 1100 AS salary FROM DUAL
UNION ALL
SELECT 4, 'Newman', 'Chad', 750 FROM DUAL
);
fiddle

Why do you want to use select statements? - Based on the values you provide it seems like you want to insert hardcoded values. Or does the dual table contain data you want to insert into HR.my_employees?
If you want to just insert values into the table, but not from an existing one, you can use the following structure:
INSERT INTO table_name (column1, column2, column3, ..., columnXX)
VALUES (value1, value2, value3, ..., valueXX);

Related

How to select a record which have all id's in SQL?

I want select record which have all id's.
Example:
Name
ID
Ram
3
Ajay
1
Mogan
3
Ram
1
Ram
2
Here Ram have all id's (1,2,3). So, I want result as Ram.
WITH CTE(NAME,CODE)AS
(
SELECT 'RAM',1 UNION ALL
SELECT'AJAY',3 UNION ALL
SELECT 'MOGAN',2 UNION ALL
SELECT 'KUMAR',3 UNION ALL
SELECT 'RAM',2 UNION ALL
SELECT 'JAYA',1 UNION ALL
SELECT 'KABIL',3 UNION ALL
SELECT 'RAM',3
)
SELECT C.NAME
FROM CTE AS C
GROUP BY C.NAME
HAVING COUNT(DISTINCT C.CODE)=(SELECT COUNT(DISTINCT CODE) FROM CTE )
As far as I know, this is called "relational division". You can try my query or look for another possible solution
Select * from table where upper(name) = 'RAM'
This query would bring back all the IDs for RAM alone
how about string agg.
CREATE TABLE MyTable (
ID int,
Name varchar(255),
);
Insert into MyTable(ID, Name) values (1, 'Ram');
Insert into MyTable(ID, Name) values (2, 'Ram');
Insert into MyTable(ID, Name) values (3, 'Ram');
Insert into MyTable(ID, Name) values (1, 'Ajay');
Insert into MyTable(ID, Name) values (1, 'Mogan');
select Name, string_agg(ID, ',') as Ids
from MyTable
group by Name;
result
Ajay 1
Mogan 1
Ram 1,2,3
see result here
http://sqlfiddle.com/#!18/923bf/4
With reference to the with clause used by #surgey above,
WITH CTE(NAME,CODE)AS
(
SELECT 'RAM',1 from dual UNION ALL
SELECT'AJAY',3 from dual UNION ALL
SELECT 'MOGAN',2 from dual UNION ALL
SELECT 'KUMAR',3 from dual UNION ALL
SELECT 'RAM',2 from dual UNION ALL
SELECT 'JAYA',1 from dual UNION ALL
SELECT 'KABIL',3 from dual UNION ALL
SELECT 'RAM',3 from dual
)
select name, code, rank() over(partition by name order by code) rank
from cte
this query, it will bring back everybody in the and group them by name. THis could be one possible solution other use tou can use an "IN" clause in your where as shown below
Select * from table where upper(name) in ('RAM','AJAY')
If are you using MySql this will solve your issue:
SELECT r1.name
FROM raws r1
LEFT JOIN raws r2 ON r1.id = r2.id AND r1.name = r2.name
WHERE r2.id IN (1, 2, 3)
GROUP by r1.name
HAVING count(r2.id) = 3; # count of numbers in IN (1, 2, 3)
And if you have identifier in your table use it for join instead
of r1.id = r2.id AND r1.name = r2.name

Insert Into command just works for one Value not for more values because of comma placement

Tried to fill in a table with insert into command, but it just works for one value not for more.
I work with MS Access and the mistake is the comma placement, but I didn't find the mistake. Tried it with just one value and that works, but I have to insert it all.
INSERT INTO Abteilung (ID, Abteilung, Mitarbeiteranzahl)
VALUES (('1', 'Einkauf', '5'), ('2', 'HR', '5'), ('3', 'Controlling', '5'),
('4', 'Produktion', '20'), ('5', 'Vertrieb', '20'),
('6', 'Qualitätsmanagement', '3'), ('7', 'Industrial Engineering', '8')
)
You can't do this as easily in access as other major db but it can be made possible. First off, create yourself a table with one row:
CREATE TABLE dual([Dummy] Integer)
INSERT INTO dual VALUES(1)
Now you can select a bunch of hard coded values "from" this table:
INSERT INTO Abteilung
(
ID,
Abteilung,
Mitarbeiteranzahl
)
SELECT '1' as e1,'Einkauf' as e2, '5' as e3 FROM dual
UNION
SELECT '2','HR','5' FROM dual
UNION
SELECT '3','Controlling','5' FROM dual
UNION
SELECT '4','Produktion','20' FROM dual
UNION
SELECT '5','Vertrieb','20' FROM dual
UNION
SELECT '6','Qulaitätsmanagement','3' FROM dual
UNION
SELECT '7','Industrial Engineering','8' FROM dual
You might need to wrap all those selects in another SELECT * FROM, I can't quite remember
By the time you're done writing all those out you might well get to thinking it would be as easy to just write N number of insert statements..
There is a way how you can insert rows without building SQL strings.
check this Answer
You can't insert more than 1 row with an INSERT statement in Access.
Even multiple INSERT statements separated with ; are not allowed.
You can use a trick though like this:
INSERT INTO Abteilung ( ID, Abteilung, Mitarbeiteranzahl)
SELECT * FROM (
SELECT '1' AS ID, 'Einkauf' AS Abteilung, '5' AS Mitarbeiteranzahl FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '2','HR','5' FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '3','Controlling','5' FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '4','Produktion','20' FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '5','Vertrieb','20' FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '6','Qulaitätsmanagement','3' FROM (SELECT COUNT(*) FROM Abteilung)
UNION ALL
SELECT '7','Industrial Engineering','8' FROM (SELECT COUNT(*) FROM Abteilung)
)
Unfortunately the FROM clause is needed for each of the INSERTs and it must return only 1 row, this is why I used SELECT COUNT(*) which for a large table may be not that efficient.
Can you try the following query:
INSERT INTO Abteilung
(
ID,
Abteilung,
Mitarbeiteranzahl
)
SELECT '1','Einkauf','5'
UNION ALL SELECT '2','HR','5'
UNION ALL SELECT '3','Controlling','5'
UNION ALL SELECT '4','Produktion','20'
UNION ALL SELECT '5','Vertrieb','20'
UNION ALL SELECT '6','Qulaitätsmanagement','3'
UNION ALL SELECT '7','Industrial Engineering','8'
Hope this should work.

SQL JOINING ISSUE

I have two different tables but both table may or may not have same records. i need to join these tables and get all the different records for both the tables
for example
CREATE TABLE sql_test_a
(
ID VARCHAR2(4000 BYTE),
FIRST_NAME VARCHAR2(200 BYTE),
LAST_NAME VARCHAR2(200 BYTE)
);
CREATE TABLE sql_test_b
(
ID VARCHAR2(4000 BYTE),
FIRST_NAME VARCHAR2(200 BYTE),
LAST_NAME VARCHAR2(200 BYTE)
);
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('1', 'John', 'Snow');
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('2', 'Mike', 'Tyson');
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('3', 'Bill', 'Keaton');
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('4', 'Greg', 'Mercury');
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('5', 'Steve', 'Jobs');
INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('6', 'Stsdsdve', 'Josdsbs');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('1', 'John', 'Snow');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('2', 'Mike', 'Tyson');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('3', 'Bill', 'Keaton');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('4', 'Greg', 'Mercury');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('5', 'Steve', 'Jobs');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('7', 'Johhny', 'Depp');
INSERT INTO sql_test_b (ID, FIRST_NAME, LAST_NAME) VALUES ('8', 'Johhnaaaay', 'Deaaap');
these are the tables and the records in the tables
and the excepted output should be
ID FIRST_NAME LAST_NAME
1 John Snow
2 Mike Tyson
3 Bill Keaton
4 Greg Mercury
5 Steve Jobs
6 Stsdsdve Josdsbs
7 Johhny Depp
8 Johhnaaaay Deaaap
i tried different join like left outer join, full outer join etc
SELECT a.ID,a.FIRST_NAME,a.LAST_NAME
FROM sql_test_a a left outer join sql_test_b b on a.ID=b.ID
and a.FIRST_NAME=b.FIRST_NAME
and a.LAST_NAME=b.LAST_NAME
this query wont give the exact output
please help
The UNION operator returns unique rows of combined queries. So, just use
SELECT * FROM sql_test_a UNION SELECT * FROM sql_test_b
To filter the result using WHERE clause you could use subquery. For example
SELECT *
FROM (SELECT * FROM sql_test_a UNION SELECT * FROM sql_test_b)
WHERE ID > 3
See also live fiddle.
If you use a union you can get the list you need (note that union all could give you duplicate rows depending on your data):
select a.id as id, a.first_name as first_name, a.last_name as last_name
from sql_test_a a
union
select b.id as id, b.first_name as first_name, b.last_name as last_name
from sql_test_b b
Using a join is discouraged in this case since it will give you a table with more than three columns, joined on (at least) one of them.
EDIT
You mention you're using oracle. To filter this, you can do several things, among which, one is wrap the query in a temporary table
with tmp as (
select a.id as id, a.first_name as first_name, a.last_name as last_name
from sql_test_a a
union
select b.id as id, b.first_name as first_name, b.last_name as last_name
from sql_test_b b
)
select tmp.id, tmp.first_name, tmp.last_name
from tmp
where
tmp.first_name like '%whatever%';
Try this Please
( SELECT * FROM sql_test_1
) UNION ALL( SELECT * FROM sql_test_b
EXCEPT
SELECT * FROM sql_test_1 )
( SELECT * FROM sql_test_a
MINUS
SELECT * FROM sql_test_b) UNION ALL( SELECT * FROM sql_test_b
MINUS
SELECT * FROM sql_test_a )

Oracle Pivot query gives columns with quotes around the column names. What?

I'm trying to use PIVOT in Oracle and I'm getting a weird result. It's probably just an option I need to set but what I know about Oracle/SQL I could fit into this comment box.
Here's an example of my query:
with testdata as
(
select 'Fred' First_Name, 10 Items from dual
union
select 'John' First_Name, 5 Items from dual
union
select 'Jane' First_Name, 12 Items from dual
union
select 'Fred' First_Name, 15 Items from dual
)
select * from testdata
pivot (
sum(Items)
for First_Name
in ('Fred','John','Jane')
The results come out as I expected except the Column names have single quotes around them (picture from Toad - if I export to Excel the quotes get carried to Excel):
How do I get rid of the single quotes around the column names? I tried taking them out in the "in" clause and I get an error:
in (Fred,John,Jane)
I also tried replacing the single quotes with double quotes and got the same error. I don't know if this is an Oracle option I need to set/unset before running my query or a Toad thing.
you can provide aliases to the new columns in the pivot statement's IN clause.
(NB: This is different from the standard where clause IN() which does not allow aliases.)
with testdata as
(
select 'Fred' First_Name, 10 Items from dual
union
select 'John' First_Name, 5 Items from dual
union
select 'Jane' First_Name, 12 Items from dual
union
select 'Fred' First_Name, 15 Items from dual
)
select * from testdata
pivot (
sum(Items)
for First_Name
in ('Fred' as fred,'John' as john,'Jane' as jane)
)
and also for your aggregate clause which is necessary if you have multiple clauses..
with testdata as
(
select 'Fred' First_Name, 10 Items from dual
union
select 'John' First_Name, 5 Items from dual
union
select 'Jane' First_Name, 12 Items from dual
union
select 'Fred' First_Name, 15 Items from dual
)
select * from testdata
pivot (
sum(Items) itmsum,
count(Items) itmcnt
for First_Name
in ('Fred' as fred,'John' as john,'Jane' as jane)
)
returns
FRED_ITMSUM FRED_ITMCNT JOHN_ITMSUM JOHN_ITMCNT JANE_ITMSUM JANE_ITMCNT
----------- ----------- ----------- ----------- ----------- -----------
25 2 5 1 12 1
Of course you can then go full circle and use standard oracle aliasing and rename them to whatever you like including putting quotes back in again..
with testdata as
(
select 'Fred' First_Name, 10 Items from dual
union
select 'John' First_Name, 5 Items from dual
union
select 'Jane' First_Name, 12 Items from dual
union
select 'Fred' First_Name, 15 Items from dual
)
select FRED_ITMSUM "Fred's Sum", FRED_ITMCNT "Fred's Count"
, JOHN_ITMSUM "John's Sum", JOHN_ITMCNT "John's Count"
, JANE_ITMSUM "Janes's Sum", JANE_ITMCNT "Janes's Count"
from testdata
pivot (
sum(Items) itmsum,
count(Items) itmcnt
for First_Name
in ('Fred' as fred,'John' as john,'Jane' as jane)
)
gives
Fred's Sum Fred's Count John's Sum John's Count Janes's Sum Janes's Count
---------- ------------ ---------- ------------ ----------- -------------
25 2 5 1 12 1

I want to make an insert using union all which has a column getting values from a sequence

I tried
INSERT INTO my_test_one (rollno,name, sirname, Dept)
(select rollno_seq.nextval,'name1','sirname1', Dept
FROM my_test_one_backup
WHERE dept = 500
UNION ALL
select rollno_seq.nextval,'name1','sirname1', Dept
FROM my_test_one_backup
WHERE dept = 501 );
While doing this I am getting the error
Error report:
SQL Error: ORA-02287: sequence number not allowed here
02287. 00000 - "sequence number not allowed here"
Don't use a UNION but a single SELECT and OR in this case:
SELECT rollno_seq.nextval,'name1','sirname1', Dept
FROM my_test_one_backup
WHERE dept = 500 OR dept = 501
Try:
INSERT INTO my_test_one
(rollno, name, sirname, Dept)
SELECT rollno_seq.nextval,
name1,
sirname1,
dept
FROM (select 'name1' as name1,'sirname1' as sirname1, Dept
FROM my_test_one_backup
WHERE dept = 500
UNION ALL
select 'name1','sirname1', Dept
FROM my_test_one_backup
WHERE dept = 501 );
Edit: Better still, use an OR like CodeBrickie says or and IN statement.
WHERE dept IN (500, 501);
Edit2:
Currently you are selecting 'name1', 'sirname1' as literals so each row returned will insert the next sequence number, 'name1', 'sirname1' and whatever the value of DEPT column is.
If your table has columns called name1 and sirname1 then you'll need to remove the single quotes (and you wouldn't need the column alias either) e.g.:
INSERT INTO my_test_one
(rollno, name, sirname, Dept)
SELECT rollno_seq.nextval,
name1,
sirname1,
dept
FROM (select name1, sirname1, Dept
FROM my_test_one_backup
WHERE dept = 500
UNION ALL
select name1, sirname1, Dept
FROM my_test_one_backup
WHERE dept = 501 );
Or
INSERT INTO my_test_one
(rollno, name, sirname, Dept)
SELECT rollno_seq.nextval,
name1,
sirname1,
dept
FROM my_test_one_backup
WHERE dept IN (500, 501);
You can't use a sequence in unioned selects, so you'll need to put the union in a sub-query and the sequence in the outer query:
INSERT INTO my_test_one (rollno,name, sirname, Dept)
select rollno_seq.nextval, name1, sirname1, dept
from (SELECT 'name1' as name1,'sirname1' as sirname1, Dept
FROM my_test_one_backup
WHERE dept = 500
UNION ALL
SELECT 'name1','sirname1', Dept
FROM my_test_one_backup
WHERE dept = 501 );
You should also note that, in SQL, double quotes indicate an object name and single quotes denote a string, so 'name1' and 'sirname1' will be static strings, not column references.