Copying data from one table to another - sql

I'm updating data by selecting data from table and inserting into another. However there are some constraints on the other table and I get this :
DETAIL: Key (entry_id)=(391) is duplicated.
I basically do this :
insert into table_tmp
select * from table_one
How can I skip insert when this key entry duplicate occurs?
Update I can't save this schema info on SQL fiddle but here it is :
CREATE TABLE table1
("entry_id" int, "text" varchar(255))
;
INSERT INTO table1
("entry_id", "text")
VALUES
(1, 'one'),
(2, 'two'),
(3, 'test'),
(3, 'test'),
(12, 'three'),
(13, 'four')
;
CREATE TABLE table2
("entry_id" int, "text" varchar(255))
;
Create unique index entry_id_idxs
on table2 (entry_id)
where text='test';
INSERT INTO table2
("entry_id", "text")
VALUES
(1, 'one'),
(2, 'two'),
(3, 'test'),
(3, 'test'),
(12, 'three'),
(13, 'four')
;
Error that I get if I try to build the schema

Insert using join that returns unmatched rows:
INSERT INTO table2
SELECT DISTINCT t1.*
FROM table1 t1
LEFT JOIN table2 t2 ON t2.entry_id = t1.entry_id
WHERE t2.entry_id IS NULL

Use this query - SQLFiddle Demo:
INSERT INTO table2
SELECT t1.* FROM table1 t1
WHERE NOT EXISTS (
SELECT entry_id
FROM table2 t2
WHERE t2.entry_id = t1.entry_id
)

Related

how to left join tables without main one

Has anybody an idea how to join below three tables into one? I have really no idea :|
create table A (id number, val varchar2(1));
create table B (id number, val varchar2(1));
create table C (id number, val varchar2(1));
insert into a (id, val) values (1, 'a');
insert into a (id, val) values (2, 'b');
insert into a (id, val) values (3, 'c');
insert into b (id, val) values (2, 'd');
insert into b (id, val) values (3, 'e');
insert into b (id, val) values (4, 'f');
insert into c (id, val) values (3, 'g');
insert into c (id, val) values (4, 'h');
insert into c (id, val) values (5, 'i');
Thanks :)
SELECT COALESCE (a.id, b.id, c.id), a.val, b.val, c.val
FROM a
FULL OUTER JOIN b ON a.id = b.id
FULL OUTER JOIN c ON b.id = c.id
order by 1
The simplest way to do what you want uses full join and using:
select *
from a full join
b
using (id) full join
c
using (id)
order by id;
Here is a db<>fiddle. This uses Oracle because of the varchar2().
Your

Distinct after join or sub-query with distinct and then join

While writing a procedure, I came across a situation were I have to put a DISTINCT in a query. This is somewhat similar to my table schema
CREATE TABLE T1
(
ID INT,
TypeID INT,
SubTypeID INT,
Name VARCHAR(50)
);
GO
CREATE TABLE T2
(
TypeID INT,
SubTypeID INT,
TypeName VARCHAR(50)
);
GO
INSERT INTO T2 (TypeID, SubTypeID, TypeName)
VALUES (1, 1, 'AAA'), (1, 2, 'AAA'),
(2, 1, 'BBB'), (2, 2, 'BBB'),
(3, 1, 'CCC'), (3, 2, 'CCC');
INSERT INTO T1 (ID, TypeID, SubTypeID, Name)
VALUES (1, 1, 1, 'ABC'), (2, 2, 2, 'BCD'),
(3, 3, 2, 'CDE'), (4, 1, 1, 'DEF'),
(5, 2, 2, 'EFG'), (6, 3, 0, 'FGH'); -- Sub Type not detected yet.
GO
In this, either user can provide the SubType or let the system to detect.
Now I have 2 query options for this scenario.
Option 1
SELECT DISTINCT t1.ID, t1.Name, t2.TypeName
FROM T1
JOIN T2 ON T1.TypeID = T2.TypeID;
And Option 2
SELECT t1.ID, t1.Name, t2.TypeName
FROM T1
JOIN (SELECT DISTINCT TypeID, TypeName FROM T2) AS T2 ON T1.TypeID = T2.TypeID;
The result is same in both the cases but I want to know which should be preferred. There may be millions of rows in table T1 and thousands of rows in T2.
In my opinion, I should use the first option to avoid subquery.
But still want to confirm with the community as it may have some or major performance impact which is not known yet.
If you care about performance, avoid select distinct in the outer query. I would try this:
SELECT t1.ID, t1.Name, t2.TypeName
FROM T1 CROSS APPLY
(SELECT DISTINCT T2.TypeName
FROM T2
WHERE T1.TypeID = T2.TypeID
) T2;

SQL statement to get all customers with no orders TODAY(current date)

The question is, how do I write a statement that would return all customers with NO Orders TODAY using sql join?
Tables : tbl_member ,tbl_order
tbl_member consist of id,name,
tbl_order consist of id, date, foodOrdered
If you left join, the select where the table on the right is nulkl, it limits to the rows that DO NOT meet the join condition:
select t1.*
from tbl_member t1
left join tbl_member t2
on t1.id = t2.id -- assuming that t2.id relates to t1.id
and t2.date = current_date() -- today's date in mysql
where t2.id is null
Assuming tbl_order date is a datetime (it probably should be) for sql server you could use something like:
declare #tbl_member table
(
id int,
fullname varchar(50)
)
declare #tbl_order table
(
id int,
orderdate datetime,
foodOrdered varchar(50)
)
INSERT INTO #tbl_member VALUES (1, 'George Washington')
INSERT INTO #tbl_member VALUES (2, 'Abraham Lincoln')
INSERT INTO #tbl_member VALUES (3, 'Mickey Mouse')
INSERT INTO #tbl_member VALUES (3, 'Donald Duck')
INSERT INTO #tbl_order VALUES (1, '2017-07-01 13:00:00', 'Fish and Chips')
INSERT INTO #tbl_order VALUES (2, '2017-07-03 08:00:00', 'Full English')
INSERT INTO #tbl_order VALUES (3, '2017-07-25 08:00:00', 'Veggie Burger')
INSERT INTO #tbl_order VALUES (3, '2017-07-25 12:00:00', 'Bangers and Mash')
SELECT id, fullname FROM #tbl_member WHERE id NOT IN
(SELECT id FROM #tbl_order
WHERE CAST(orderDate as date) = CAST(GETDATE() as Date))
It helps if you specify what flavour database you are using as the syntax is often subtly different.

How to update date in table based on two criteria from a select

I need to update a date in one table based on if an userID and planName are returned from a select off a different table.
Something like
UPDATE Table A
SET DATE = GETDATE()
WHERE userid AND planName IN (SELECT userid, planName From Table B)
The simplest method is to join these two tables in an UPDATE statement.
Try the following:
UPDATE [Table A]
SET DATE = GETDATE()
FROM [Table A] a
INNER JOIN [Table B] b on a.userid = b.userid and a.planName = b.planName
I think this is what you looking for:
UPDATE A
SET
A.DATE = GETDATE()
FROM TableA AS A
WHERE EXISTS
(
SELECT 1
FROM TableB AS B
WHERE B.userid = A.userid
AND B.planName = A.planName
);
this will update all the rows in your table A that have the exact combination(s) of userid and planName that exist in table B
so if Table A has the following:
userid planName
1 A
2 A
1 B
and Table B has the following
userid planName
1 A
1 B
it will only update the following in Table A:
userid planName
1 A
1 B
See if this helps...
-- some test data...
IF OBJECT_ID('tempdb..#TableA', 'U') IS NOT NULL
DROP TABLE #TableA;
CREATE TABLE #TableA (
UserID INT NOT NULL,
PlanName VARCHAR(5) NOT NULL,
SomeDate DATE NULL,
PRIMARY KEY CLUSTERED (UserID)
);
IF OBJECT_ID('tempdb..#TableB', 'U') IS NOT NULL
DROP TABLE #TableB;
CREATE TABLE #TableB (
UserID INT NOT NULL,
PlanName VARCHAR(5) NOT NULL,
PRIMARY KEY CLUSTERED (UserID, PlanName)
);
INSERT #TableA (UserID, PlanName) VALUES
(1, 'aaa'), (2, 'aab'), (3, 'abb'),
(4, 'aaa'), (5, 'aab'), (6, 'ccc');
INSERT #TableB (UserID, PlanName) VALUES
(1, 'aaa'), (1, 'abb'), (1, 'bbb'),
(2, 'aaa'), (2, 'abb'), (2, 'bbb'),
(3, 'aaa'), (3, 'abb'), (3, 'bbb'),
(4, 'aaa'), (4, 'abb'), (4, 'bbb'),
(5, 'aaa'), (5, 'abb'), (5, 'bbb'),
(6, 'aaa'), (6, 'abb'), (6, 'bbb');
--=========================================
-- check initial values...
SELECT * FROM #TableA ta;
SELECT * FROM #TableB tb;
-- written as a SELECT...
SELECT
*
FROM
#TableA ta
WHERE
EXISTS (SELECT 1 FROM #TableB tb WHERE ta.UserID = tb.UserID AND ta.PlanName = tb.PlanName);
-- written as an UPDATE...
UPDATE ta SET
ta.SomeDate = GETDATE()
FROM
#TableA ta
WHERE
EXISTS (SELECT 1 FROM #TableB tb WHERE ta.UserID = tb.UserID AND ta.PlanName = tb.PlanName);
-- check updated values...
SELECT * FROM #TableA ta;
This was able to get it:
WITH CTE (userid, planName)
AS (SELECT userid, planName From Table B)
UPDATE A
SET DATE = GETDATE()
FROM Table A
JOIN CTE B
ON B.userid = A.userid AND B.planName = A.planName

Is it possible to Left outer join normal table with temp table?

I create SQL server query and have normal table with records and in the other hand have a temp table with record and this table not empty and all fields doesn't have any conflict to
join
is possible to join this two different type table?
SELECT NormalTable.Entityname FROM NormalTable LEFT JOIN
#Temp tmp ON tmp.joinID = NormalTable.joinID
is possible to join this two different type table? (normal and temporary)
Yes it is possible to join different type of table (permanent and temporary tables). There is no different syntax to join these tables.
E.g.
Permanent table:
CREATE TABLE NormalTable
([plateno] varchar(1), [JoinID] int)
;
INSERT INTO NormalTable
([plateno], [JoinID])
VALUES
('A', 1),
('B', 2),
('C', 2),
('A', 3),
('B', 2),
('A', 4),
('A', 1)
;
Temporary table:
CREATE TABLE #Temp
([id] int, [date] date, [score] int)
;
INSERT INTO #Temp
([id], [date], [score])
VALUES
(1, '2013-04-13', 100),
(2, '2013-04-14', 92),
(3, '2013-04-15', 33)
;
Join both tables:
SELECT N.* FROM NormalTable N
LEFT JOIN #Temp T ON N.JoinID = T.ID
Have a look at this SQLFiddle