sql server insert value in existing column - sql-server

I have an Employee table as following
I want to insert values 4,3,7,8,4,12,10,10,6,NULL,3,10 in existing column [manager] which I had created using query
ALTER TABLE employee ADD manager INT NULL;

Something like the following is what you need, construct the explicit list of values and then simply join to it in an update
with d as (
select *
from (
values
(1,4),
(2,3),
(3,7),
(4,8),
(5,4),
(6,12),
(7,10),
(8,10),
(9,6),
(11,3),
(12,10)
)x(emp_id,manager)
)
update e set
e.manager=d.manager
from d join Employee e on e.emp_id=d.emp_id

Related

How is this SQL sub-query correctly vectorising?

Sample data:
CREATE TABLE Departments (
Code INTEGER PRIMARY KEY,
Name varchar(255) NOT NULL ,
Budget decimal NOT NULL
);
CREATE TABLE Employees (
SSN INTEGER PRIMARY KEY,
Name varchar(255) NOT NULL ,
LastName varchar(255) NOT NULL ,
Department INTEGER NOT NULL ,
foreign key (department) references Departments(Code)
)
INSERT INTO Departments(Code,Name,Budget) VALUES(14,'IT',65000);
INSERT INTO Departments(Code,Name,Budget) VALUES(37,'Accounting',15000);
INSERT INTO Departments(Code,Name,Budget) VALUES(59,'Human Resources',240000);
INSERT INTO Departments(Code,Name,Budget) VALUES(77,'Research',55000);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('123234877','Michael','Rogers',14);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('152934485','Anand','Manikutty',14);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('222364883','Carol','Smith',37);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('326587417','Joe','Stevens',37);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('332154719','Mary-Anne','Foster',14);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('332569843','George','O''Donnell',77);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('546523478','John','Doe',59);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('631231482','David','Smith',77);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('654873219','Zacary','Efron',59);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('745685214','Eric','Goldsmith',59);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('845657245','Elizabeth','Doe',14);
INSERT INTO Employees(SSN,Name,LastName,Department) VALUES('845657246','Kumar','Swamy',14);
Problem: "Select the names of departments with more than two employees."
Wikibooks solution:
/*With subquery*/
SELECT D.Name FROM Departments D
WHERE 2 <
(
SELECT COUNT(*)
FROM Employees
WHERE Department = D.Code
);
My question: How does this solution work? That is, how does MSSQL know which values in Departments are to be kept from the sub-query? I can't see any way that the condition WHERE Department = D.Code can return a result that is ordered in a useful way to the outer query. I don't think that this is a fluke, I think that I just don't understand how SQL is vectorised.
This is called a correlated subquery.
That is to say, the inner query is correlated to the outer one by use of an outer reference. In this case, that is D.Code. Therefore the subquery is being calculated for every row of D.
It's not a matter of ordering, in fact this query can return results in any order. But the result from the subquery must be greater than 2 otherwise the WHERE predicate fails.
SELECT D.Name FROM Departments D -- Departments has been aliased as D
WHERE 2 <
(
SELECT COUNT(*)
FROM Employees
WHERE Department = D.Code -- Here the inner query is being limited by
-- the reference to the outer D table
);
I would probably use ... > 2 rather than 2 < ...
Side point: It's better to always use an explicit table reference in subqueries, eg e.Department = D.Code, because otherwise you could misspell a column and end up referring to an outer column instead of an inner column, and the correlation wouldn't work properly

Best way to attack a confusing SQL issue in inserting data into a TEMP table

I'm working in SQL Server 2016. Confusing problem with SQL issue. I have a TEMP table that contains unique rows. I have to insert 5 PRODUCTID values for each row each row based on another column value, AgentNo, in this temp table. The PRODUCTID value, there are 5 of them, comes from another table but there is no relationship between the tables. So my question is how do I insert a row for each ProductID into this temp table for each unique row that is currently in the temp table.
Here is a pic of the TEMP table that requires 5 rows for each:
Here is a pic of what I'm needing to come away with:
Here is my SQL code for both TEMP tables:
IF OBJECT_ID('tempdb..#tempTarget') IS NOT NULL DROP TABLE #tempTarget
SELECT 0 as ProductID, 1 as [Status], a.AgentNo, u.UserID, u.[Password], 'N' as AdminID, tel.LocationSysID --, tel.OwnerID, tel.LocationName, a.OwnerSysID, a.AgentName
INTO #tempTarget
FROM dbo.TEST_EvalLocations tel
INNER JOIN dbo.AGT_Agent a
ON tel.LocationName = a.AgentName
INNER JOIN dbo.IW_User u
ON a.AgentNo = u.UserID
WHERE tel.OwnerID = 13313
AND tel.LocationSysID <> 15434;
SELECT * FROM #tempTarget WHERE LocationSysID NOT IN (15425, 15434);
GO
-- Create source table
IF OBJECT_ID('tempdb..#tempSource') IS NOT NULL DROP TABLE #tempSource
SELECT DISTINCT lpr.ProductID
INTO #tempSource
FROM dbo.Eval_LocationProductRelationship lpr
WHERE lpr.ProductID IN (16, 15, 13, 14, 12) --BETWEEN 15435 AND 15595
Sorry I could not get this into a DDL file as these are TEMP tabless. Any help/direction would be appreciated. Thanks.
CROSS JOIN will be the best solution for your case.
If you only want 5 rows for each data in First table means, simply use the below cross join query.
SELECT B.ProductID,
A.[Status],
A.AgentNo,
A.UserID,
A.[Password] AS Value,
A.AdminID,
A.LocationSysID
FROM #tempTarget A
CROSS JOIN tempSource B
If you want additional row with 0, then you have to insert a 0 into your second temp table and use the same query.
INSERT INTO #tempSource SELECT 0
If i understand correctly following is the scenario,
One Temp table has all the content.
select * from #withoutProducts
product table
select * from #products
Then following is the query your are looking for
select a.ProductID,[Status],AgentNo,UserID,[value]
from #products a cross join #withoutProducts b
order by AgentNO,a.productID

SQL Server 2008: Unique constraint for values non-related with columns

I have a simple problem. How can I add a unique constraint for a table, without relating the values to their columns? For example, I have this table
ID_A ID_B
----------
1 2
... ...
In that example, I have the record (1,2). For me, (1,2) = (2,1). So i don't want to allow my database to store both values. I know I can accomplish it using, triggers or checks and functions. But i was wondering if there is any instruccion like
CREATE UNIQUE CONSTRAINT AS A SET_CONSTRAINT
You could write a view like that:
select 1 as Dummy
from T t1
join T t2 on t1.ID1 = t2.ID2 AND t1.ID2 = t2.ID1 --join to corresponding row
cross join TwoRows
And create a unique index on Dummy. TwoRows is a table that contains two rows with arbitrary contents. It is supposed to make the unique index fail if there ever is a row in it. Any row in this view indicates a uniqueness violation.
You can do this using Instead of Insert trigger.
Demo
Table Schema
CREATE TABLE te(ID_A INT,ID_B INT)
INSERT te VALUES ( 1,2)
Trigger
Go
CREATE TRIGGER trg_name
ON te
instead OF INSERT
AS
BEGIN
IF EXISTS (SELECT 1
FROM inserted a
WHERE EXISTS (SELECT 1
FROM te b
WHERE ( ( a.id_a = b.id_b
AND a.id_b = b.id_a )
OR ( a.id_a = b.id_a
AND a.id_b = b.id_b ) )))
BEGIN
PRINT 'duplciate record'
ROLLBACK
END
ELSE
INSERT INTO te
SELECT Id_a,id_b
FROM inserted
END
SELECT * FROM te
Insert Script
INSERT INTO te VALUES (2,1) -- Duplicate
INSERT INTO te VALUES (1,2) --Duplicate
INSERT INTO te VALUES (3,2) --Will work

insert into existing temp table in sql server

I have created a temp table in sql server and inserted values to it.
If the values of a particular column are null i need to fill using some values from another table. How to query this?
sample data given below.
select 'name' as name,3 as age,'email' as email into #tmp1 from table1
Now if the column age is empty i need to insert a value to the column age to all the existing records in tmp1.
INSERT INTO #tmp1 (age)SELECT age AS [age] FROM table2 WHERE name=#name
But it inserts a new record.
please help.
You want UPDATE, not INSERT
Something like this:
UPDATE #tmp1
SET age = Table2.Age
FROM table2
WHERE #tmp1.Age IS NULL
AND #tmp1.Name = Table2.Name
You need to do update not Insert:
Update a
a.age = b.age
from
(select id,age from table where age is null) a
inner join
table b
ON a.id = b.id

insert results of join in SQL server 2005

I have two tables with more than 800 rows in each.Table names are 'education' and 'sanitation'.The column name 'ID' is common in both the tables.Now i want to join these both tables as full outer join and i want to save the results of this table as a new table.I can join it very easily,But how to save those data's as a new table.Please help Me.
select * into bc from education e join sanitation s on e.id=s.id
I have around 30 columns in each table.So i can not explicitly create table schema for a new table.
I want all the columns from both tables.I have 20 tables with each 800 rows.From this 20 tables i want to make one master table taking 'ID' as primary key in all.
Sample Code:
Table one:
create table dummy1(
id int , fname varchar(50)
)
insert into dummy1 (id,fname) values (1,'aaa')
insert into dummy1 (id,fname) values (2,'bbb')
insert into dummy1 (id,fname) values (3,'ccc')
insert into dummy1 (id,fname) values (3,'ccc')
Table Two
create table dummy2(
id int , lname varchar(50)
)
insert into dummy2 (id,lname) values (1,'abc')
insert into dummy2 (id,lname) values (2,'pqr')
insert into dummy2 (id,lname) values (3,'mno')
Now Create new table 3
create table dummy3(
id int , fname varchar(50),lname varchar(50)
)
Insert Query for table 3 look like
insert into dummy3 (id,fname,lname)
(select a.id,a.fname,b.lname from dummy1 a inner join dummy2 b on a.id=b.id)
Table 3 will contain table1, table2 data
Follow below:
SELECT t1.Column1, t2.Columnx
INTO DestinationTable
FROm education t1
INNER JOIN sanitation t2 ON t1.Id = t2.Id
EDIT:
SELECT * will not work for you because you have a column ID which exists in both the tables. So the above solution will work you.
EDIT:
1- You can temporarily rename the Id column in one table, then try
2- SELECT *
INTO DestinationTable
FROm education t1
INNER JOIN sanitation t2 ON t1.Id = t2.Id
3- Revert the column name back to Id.

Resources