Insert value from three tables into an empty table - sql

I need to select FirstName, LastName, deliver_date, order_id, total_price from table 1, table 2, table 3 according to id and order_id and put those into table 4.
Table 1
id FirstName LastName
-------------------------
1 mr.xxxx xxx
2 mr.ssss sss
3 mr.yyyy yyy
Table 2
order_id deliver_date id tracking_number
----------------------------------------------
01 10/01/2017 1 1
02 10/01/2017 2 2
03 10/01/2017 3 3
Table 3
order_id total_price item qty
-----------------------------------------------
01 some price xx some quantity xx
02 some price xx some quantity xx
03 some price xx some quantity xx
Table 4
FirstName, LastName, deliver_date, order_id, total_price
I try to do it like this:
INSERT INTO RECEIPT (CUST_FNAME, CUST_LNAME, CUST_EMAIL, CUST_MOBILE, CUST_ADDRESS, CUST_CITY, CUST_STATE, CUST_POSTCODE, DELIVERY_DATE, TOTAL_PRICE, CUST_ID, ORDER_ID)
VALUES (SELECT CUSTOMER.CUST_FNAME, CUSTOMER.CUST_LNAME, CUSTOMER.CUST_EMAIL, CUSTOMER.CUST_MOBILE, CUSTOMER.CUST_ADDRESS, CUSTOMER.CUST_CITY, CUSTOMER.CUST_STATE, CUSTOMER.CUST_POSTCODE , ORDERS.DELIVERY_DATE, "ORDER DETAIL".TOTAL_PRICE, ORDERS.CUST_ID, ORDERS.ORDER_ID FROM CUSTOMER, ORDERS, "ORDER DETAIL" WHERE CUSTOMER.CUST_ID = ORDERS.CUST_ID AND ORDERS.ORDER_ID = "ORDER DETAIL".ORDER_ID)
But I get an error :
SQL0412N Multiple columns are returned from a subquery that is allowed only one column. SQLSTATE=42823

When using INSERT statement while selecting data from another table, you need to omit VALUES keyword.
So, it should be
INSERT INTO <TABLE_NAME>(col1, col2...)
SELECT col1, col2...
Also, make sure have same number of columns with same in same sequence, otherwise, you will be inserting wrong values or your query will throw error due to mis-match data type.

try this:
insert into table4 (FirstName, LastName, deliver_date, order_id, total_price)
select f1.FirstName, f1.LastName, f2.deliver_date, f2.order_id, f3.total_price
from table1 f1
inner join table2 f2 on f1.id=f2.id
inner join table3 f3 on f2.order_id=f3.order_id

You have the error in " ...VALUES (SELECT CUSTOMER.CUST_FNAME, ... " in the first column to insert, maybe this sub-query has more than 1 row.
You must adjust this query to return 1 row only (more filters).
Anyway other form to backup your values to another new table, is selecting the exactly columns from your new table and save this query into a .csv file.
Example:
CREATE TABLE new_table
(
id SERIAL NOT NULL,
FirstName VARCHAR,
LastName VARCHAR
....
);
SELECT table1.FirstName, table2.LastName, ...
FROM table1
INNER JOIN ....
-- this query you must save into a csv file (if your DB engine is allowed to save to csv).
After you have the file ready, you must load again in the new table.

Related

Adding a Varchar auto-increment column to an select query

I'm trying to design a database and I have grouped a certain data as follows
select Name, prod_cat, prod_country, count(*)
from table1
group by Name, prod_cat, prod_country
union
select Name, prod_cat, prod_country, count(*)
from table2
group by Name, prod_cat, prod_country
Now for the resultant data from the query above, I would like to add an auto-increment ID as a VARCHAR column which should start as 'U000001' , 'U000002' , 'U000003' , 'U000004' ... all the way to the last column
For a better database, is it better to put the resultant query into a temporary table/view or is it better to use a stored procedure as there could be more data coming in
How can I add an auto-incrementing ID VARCHAR column to the above mentioned select query? Should I use Declare and increment?
Expected result :
Prod_ID
Name
Prod_cat
Prod_country
U000001
abc
12
USA
U000002
efg
1
IND
U000003
def
3
MEX
U000004
ijk
21
CHN

How to sum column values from two tables and preserve another column which is only in one table

i have created tables item and item2, I know maybe it's data redundancy but i want to know how can select it, and create a view?
create table item(
id number(10) primary key,
name varchar2(20),
mark number(10));
insert into item values(10,'Apple1',23);
insert into item values(11,'Apple2',0);
insert into item values(12,'Apple3',0);
insert into item values(13,'Apple4',0);
insert into item values(14,'Apple4',0);
insert into item values(15,'Apple4',0);
insert into item values(16,'Apple4',0);
create table item2(
id number(10),
mark number(10));
alter table item2 add(constraint id_fk FOREIGN KEY (id) references item(id));
Insert into item2 values(10,1);
Insert into item2 values(10,1);
Insert into item2 values(11,7);
Insert into item2 values(12,14);
I can query both:
select * from item;
ID Name Mark
10 Apple1 23
11 Apple2 0
12 Apple3 0
13 Apple4 0
14 Apple4 0
15 Apple4 0
16 Apple4 0
select * from item2;
ID Mark
10 1
10 1
11 7
12 14
I want to get the result set below using the select statement sum from the item and item2 tables:
ID Name Mark
10 Apple1 25
11 Apple2 7
12 Apple3 14
13 Apple4 0
14 Apple4 0
15 Apple4 0
16 Apple4 0
How can I combine my queries to produce that output?
If I understand this correctly, you want to "pretend" that the second table had the NAME column also, populated according to the first table; then you would want to GROUP BY id and get the sum of MARK.
If so, instead of joining the tables to get the names (either before or after combining the tables and computing the sums), you can use a UNION ALL, in which you insert a fake NAME column with NULL in it for the second table; then you group by id, you sum the MARK column, and you take the MAX over NAME. MAX ignores NULL, so it will just pick the name from table ITEM.
The solution below follows that logic in every detail.
select id, max(name) as name, sum(mark) as mark
from ( select id, name, mark
from item
union all
select id, null as name, mark
from item2
)
group by id
;
You can union the two tables together on the id and mark. The name you can either add a null name column into the union and do a max/min on that field to get one value from that table. Otherwise you can union the id and marks, and then join back to the original table with the name to grab it from there and include it in the group by.
select item_table.id, item_table.name, sum(mark_data_set.mark) as mark_score
from
(select
id, mark
from item
union all
select id, mark
from item2
) mark_data_set
inner join item item_table on (mark_data_set.id = item_table.id)
group by item_table.id, item_table.name
How about this?
select id,name,(m1 +nvl(m2,0)) mark
from
(select t1.id,t1.name,t1.mark m1,t2.mark m2
from
item t1
LEFT OUTER JOIN
(select id,sum(mark) mark from item2
group by id) t2
ON
t2.id = t1.id
)
order by id;

How to select last insert value for specific column

I have a two tables and details are give below:
create table pbc(
id number(5) primary key,
name varchar2(15));
insert into pbc values(2,'product1');
insert into pbc values(3,'product1');
insert into pbc values(4,'product1');
insert into pbc values(5,'product1');
insert into pbc values(6,'product1');
insert into pbc values(7,'product1');
and the other table is
create table zxy(
id number(5),
price number(10));
alter table zxy add(constraint zxyid_fk FOREIGN KEY (id) references pbc(id));
insert into zxy values(2,67);
insert into zxy values(3,34);
insert into zxy values(3,21);
insert into zxy values(4,65);
insert into zxy values(5,32);
insert into zxy values(5,23);
insert into zxy values(5,10);
second table select data are given below
Id price
2 67
3 34
3 21
4 65
5 32
5 23
5 10
now i have to select last inserting values such as
id price
2 67
3 21
4 65
5 10
I do not want to max price I want to last insert price
There is no way to say which value was inserted last. For ID 3 there are two prices 34 and 21, but nothing to indicate when the records got inserted. Data in tables has no inherent order; the records are considered unordered.
You need a date or something to indicate insert order.
If the table already exists this way, you are lost, because you cannot know which values are current and which are out-dated. If this is a new table and you only plan to fill it later, then add a date and a trigger to fill the date with sysdate on insert.
Based on the requirements, I don't see any usage of the first table. Try:
SELECT Z.ID, B.PRICE
FROM
(
SELECT A.ID, MAX(A.RNUM) AS LAST_INSERTED
FROM
(SELECT ID, PRICE, ROW_NUMBER() OVER (PARTITION BY ID) AS RNUM FROM ZXY) A
GROUP BY A.ID
) Z
INNER JOIN
(SELECT ID, PRICE, ROW_NUMBER() OVER (PARTITION BY ID) AS RNUM FROM ZXY) B
ON Z.ID = B.ID AND Z.LAST_INSERTED = B.RNUM;

One SQL statement for counting the records in the master table based on matching records in the detail table?

I have the following master table called Master and sample data
ID---------------Date
1 2014-09-07
2 2014-09-07
3 2014-09-08
The following details table called Details
masterId-------------Name
1 John Walsh
1 John Jones
2 John Carney
1 Peter Lewis
3 John Wilson
Now I want to find out the count of Master records (grouped on the Date column) whose corresponding details record with Name having the value "John".
I cannot figure how to write a single SQL statement for this job.
**Please note that join is needed in order to find master records for count. However, such join creates duplicate master records for count. I need to remove such duplicate records from being counted when grouping on the Date column in the Master table.
The correct results should be:
count: grouped on Date column
2 2014-09-07
1 2014-09-08
**
Thanks and regards!
This answer assumes the following
The Name field is always FirstName LastName
You are looking once and only once for the John firstname. The search criteria would be different, pending what you need
SELECT Date, Count(*)
FROM tblmaster
INNER JOIN tbldetails ON tblmaster.ID=tbldetails.masterId
WHERE NAME LIKE 'John%'
GROUP BY Date, tbldetails.masterId
What we're doing here is using a wilcard character in our string search to say "Look for John where any characters of any length follows".
Also, here is a way to create table variables based on what we're working with
DECLARE #tblmaster as table(
ID int,
[date] datetime
)
DECLARE #tbldetails as table(
masterID int,
name varchar(50)
)
INSERT INTO #tblmaster (ID,[date])
VALUES
(1,'2014-09-07'),(2,'2014-09-07'),(3,'2014-09-08')
INSERT INTO #tbldetails(masterID, name) VALUES
(1,'John Walsh'),
(1,'John Jones'),
(2,'John Carney'),
(1,'Peter Lewis'),
(3,'John Wilson')
Based on all comments below, this SQL statement in it's clunky glory should do the trick.
SELECT date,count(t1.ID) FROM #tblmaster mainTable INNER JOIN
(
SELECT ID, COUNT(*) as countOfAll
FROM #tblmaster t1
INNER JOIN #tbldetails t2 ON t1.ID=t2.masterId
WHERE NAME LIKE 'John%'
GROUP BY id)
as t1 on t1.ID = mainTable.id
GROUP BY mainTable.date
Is this what you want?
select date, count(distinct m.id)
from master m join
details d
on d.masterid = m.id
where name like '%John%'
group by date;

Merge 2 tables into 1 SQL Server

This is my current table:
Sales Table
OrderID Customer_ID Customer_Name
1 12 Bob
2 18 Ben
3 11 Harry
OrderID is the primary key
I have a temporary table Temp1:
Order_CreateDate Order_ReturnDate
20051102 20051104
20051103 20051108
20051104 20051105
I want to change the dates YYYYMMDD in Temp1 table, to YYYY-MM-DD, and move it to table, this code below does not work if I insert straight into Sales Table as it displays error saying:
Cannot insert the value NULL into column 'Order_ID', table 'car_rental.dbo.DataInCentralDatabase2'; column does not allow nulls. INSERT fails
However if I test it out by outputting to another temporary table, temp2, it works.
INSERT INTO [dbo].[sales]([Order_CreateDate])
SELECT
CONVERT(date,Order_CreateDate,111) AS Order_CreateDate
FROM dbo.temp1
But running this code two times for temp2 table (for the two converted columns) has the following result:
Order_CreateDate Order_ReturnDate
2005-11-02
2005-11-03
2005-11-04
NULL 2005-11-04
NULL 2005-11-08
NULL 2005-11-05
I know this question is extremely confusing, but as the end result I want it to become like this:
OrderID Customer_ID Customer_Name Order_CreateDate Order_ReturnDate
1 12 Bob 2005-11-02 2005-11-04
2 18 Ben 2005-11-03 2005-11-08
3 11 Harry 2005-11-04 2005-11-05
Any ideas on how to tackle this?
You need another column in Temp1 table as
OrderID Order_CreateDate Order_ReturnDate
1 20051102 20051104
2 20051103 20051108
3 20051104 20051105
Use Update query and not Insert query
UPDATE a set
Order_CreateDate=CONVERT(datetime,b.Order_CreateDate,111),
Order_ReturnDate=CONVERT(datetime,b.Order_ReturnDate,111)
from [dbo].[sales] a join [dbo].[Temp1] b on a.OrderID = b.OrderID
At the first, you should get an updated version of temp1 like this:
select
CONVERT(date,Order_CreateDate,111) as Order_CreateDate,
CONVERT(date,Order_ReturnDate,111) as Order_ReturnDate,
OrderID
into #temp2
from temp1
then, update your main table with join on temp1, like this:
update s
s.Order_CreateDate = t.Order_CreateDate,
s.Order_ReturnDate = t.Order_ReturnDate
from sales s
inner join #temp2 t
on s.OrderID = t.OrderID