Insert into table with where condition - sql-server

I have two tables
Table1
OfficeID OfficeName
-------------------
1 UK
2 JP
3 US1
4 US2
5 US3
6 US4
OfficeID is an identity auto increment column.
I need to add couple of more offices (e.g. US5,US6) into table1:
insert into Table1 (OfficeName)
values ('US5'), ('US6')
I have another table2
OrgID OfficeID
----------------
1 1
2 2
3 3
3 4
3 5
3 6
After inserting the US5 and US6 the new data in table 1 will be
OfficeID OfficeName
-------------------
1 UK
2 JP
3 US1
4 US2
5 US3
6 US4
7 US5
8 US6
After this, I would like to insert officeID into table 2 so that my table 2 would look like this:
OrgID OfficeID
----------------
1 1
2 2
3 3
3 4
3 5
3 6
3 7
3 8
Here is how I'm trying to do this
insert into Table2 (OfficeID)
select OfficeID
from table1
where OfficeID in ((7), (8))
and table2.OrgID = 3
How to achieve this? Thanks

You should define all columns you want to insert:
insert into Table2 (OfficeID, OrgID)
select OfficeID, 3 from table1 where OfficeID in ((7),(8))

If you want identity column to be inserted into Table2 try OUTPUT clause
Insert into Table1 (OfficeName)
OUTPUT inserted.OfficeID, 3 INTO Table2 (OfficeID, OrgID)
values
('US5'),
('UK6')
go

try to make a inner join to the table 2 because you are trying to filter by column on table 2 and are inaccesable in the select statement, try this
INSERT INTO Table2 (OfficeID)
SELECT OfficeID FROM table1 INNER JOIN table2 ON (CLAUSE) WHERE table1.OfficeID in ((7),(8))
AND table2.OrgID=3

Related

List combination in where clause

Here is the scenerio, I have a input data and a table table1
Input Data Table1
Customer Id Campaign ID CustomerId CampaignID
1 1 4 2
1 2 6 3
2 3 1 1
1 3 5 5
4 2 9 8
4 4
5 5
I want to query table1 such that it return only those values from the where clause which are not present in table1. So the result will be as below
Result
Customer Id Campaign ID
1 2
2 3
1 3
4 4
5 5
So the query should be something like
select CustomerId, CampaignID from Table1
where Customer Id in (Input data for customer id) and CampaignId in (Input data for campaign id)
. I know this query is not right, but can someone please help.
Is there a way to filter the values given in where clause based on if they are present in table1?
P.S. table1 primary key (CustomerId, CampaignID)
This will work as for your scenario. But it wont show last result record 5,5 since it does not fulfill your need.
select * from input where (cust_id, camp_id) not in (select cust_id, camp_id from table1)

Update only Top 1 OR anyone row of a table using join with another table

I want to Update only top 1 OR only 1 row of a column where a column values are same.
(Just logical explanation don't go on syntax)
LIKE:
Update [Total] = (value from a another table with a common column)
but need to update only top 1 row OR any one row to the current (updating) table not all rows matching column value...
e.g
Table 1:
Skill Value
abc 3
def 4
xyz 3.5
Table 2:
Name Skill MyValue MyValue2(ColumnNeedsToBeUpdated)
Ram abc 3
shyam abc 4
Mohan abc 5
Raju xyz 4
Ratan xyz 6
Now I want to Update MyValue2 based on Table1 column Skill Value = MyValue2 but I want to update anyone OR top 1 row in Table2 NOT ALL Please help
Expected Output:
Name Skill MyValue MyValue2(ColumnNeedsToBeUpdated)
Ram abc 3 3
shyam abc 4
Mohan abc 5
Raju xyz 4 3.5
Ratan xyz 6
OR Alternate output can be:
Name Skill MyValue MyValue2(ColumnNeedsToBeUpdated)
Ram abc 3 Value from Table1 / no. of records with skill abc (3/3)
shyam abc 4
Mohan abc 5
Raju xyz 4 Value from Table1 / no. of records with skill xyz (3.5/2)
Ratan xyz 6
In Table 2, give a row number based on group by Skill column and order by MyValue column. And then updated the rows which having row number1 with Value from Table 1.
Query
;with cte as(
select [rn] = row_number() over(
partition by Skill
order by [MyValue]
), *
from [Table2]
)
update t1
set t1.[MyValue2] = t2.[Value]
from cte t1
join [Table1] t2
on t1.[Skill] = t2.[Skill]
where t1.[rn] = 1;

Using Recursive CTE with GroupBy

I am new to the recursive CTE concept and a problem at hand, I got a tiny feeling that the problem can be solved by using recursive CTE. Let me know what you guys think.
Two tables:
Table one is a self referencing Location table with ID, ParentID, Level and Description.
Table two is an asset table which records individual assets and has a foreign key to Location table ID field.
Table1:
ID Description ParentID Level
1 Site1 NULL 1
2 Site2 NULL 1
3 Building1 1 2
4 Building2 1 2
5 Floor1 3 3
6 Floor2 3 3
7 Floor3 4 3
8 Place1 5 4
9 Place2 7 4
Table2:
ID Description Quantity LocationID
1 Desk 3 8
2 Lamp 1 8
3 PC 10 9
I would like to create a stored procedure with a input parameter of #Level and returns all the Location records at that level and the number of assets within the location (including sub levels).
For example, if #Level = 3, the stored procedure should return:
ID Description AssetCount
5 Floor1 4
6 Floor2 0
7 Floor3 10
If #Level = 2, the stored procedure should return:
ID Description AssetCount
3 Building1 4
4 Building2 10
If the problem is not clear, please let me know.
Well, nothing special here, just a recursive CTE joined with the other table, and the results are what you expected:
declare #level int = 3
;with CTE as (
select id as origid, id, Description, parentid
from table1 where level = #level
union all
select CTE.origid, t1.id, CTE.Description, t1.parentid
from CTE join table1 t1 on
CTE.id = t1.parentid
)
select origid, CTE.description, isnull(sum(t2.Quantity),0) as Quantity
from CTE left outer join table2 t2 on CTE.id = t2.locationid
group by origid, CTE.description
SQL Fiddle

SQL Update row column with random lookup value

I am trying to update a lead table to assign a random person from a lookup table. Here is the generic schema:
TableA (header),
ID int,
name varchar (30)
TableB (detail),
ID int,
fkTableA int, (foreign key to TableA.ID)
recordOwner varchar(30) null
other detail colums..
TableC (owners),
ID int,
fkTableA int (foreign key to TableA.ID)
name varchar(30)
TableA has 10 entries, one for each type of sales lead pool. TableB has thousands of entries for each row in TableA. I want to assign the correct recordOwners from TableC to and even number of rows each (or as close as I can). TableC will have anywhere from one entry for each row in tableA or up to 10.
Can this be done in one statement? It doesn't have to be. I can't seem to figure out the best approach for speed. Any thoughts or samples are appreciated.
Updated:
TableA has a 1 to many relation ship with TableC. For every record of TableA, TableC will have at least one row, which represents an owner that will need to be assigned to a row in TableB.
TableA
int name
1 LeadSourceOne
2 LeadSourceTwo
TableC
int(id) int(fkTableA) varchar(name)
1 1 Tom
2 1 Bob
3 2 Timmy
4 2 John
5 2 Steve
6 2 Bill
TableB initial data
int(id) int(fkTableA) varchar(recordOwner) (other detail columns)
1 1 NULL ....
2 1 NULL ....
3 1 NULL ....
4 2 NULL ....
5 2 NULL ....
6 2 NULL ....
7 2 NULL ....
8 2 NULL ....
9 2 NULL ....
TableB end result
int(id) int(fkTableA) varchar(recordOwner) (other detail columns)
1 1 TOM ....
2 1 BOB ....
3 1 TOM ....
4 2 TIMMY ....
5 2 JOHN ....
6 2 STEVE ....
7 2 BILL ....
8 2 TIMMY ....
9 2 BILL ....
Basically I need to randomly assign a record from tableC to tableB based on the relationship to tableA.
UPDATE TabB SET name = (SELECT TOP 1 coalesce(tabC.name,'') FROM TabC INNER JOIN TabA ON TabC.idA = TabA.id WHERE tabA.Id = TabB.idA )
Should work but its not tested.
Try this:
UPDATE TableB
SET recordOwner = (SELECT TOP(1) [name]
FROM TableC
ORDER BY NEWID())
WHERE recordOwner IS NULL
I ended up looping thru and updating x percent of the detail records based on how many owners I had. The end result is something like this:
create table #tb_owners(userId varchar(30), processed bit)
insert into #tb_owners(
userId,
processed)
select userId = name,
processed = 0
from tableC
where fkTableA = 1
select #percentUpdate = cast(100 / count(*) as numeric(8,2))
from #tb_owners
while exists(select 1 from #tb_owners o where o.processed = 0)
begin
select top 1
#userFullName = o.name
from #tb_owners o
where o.processed = 0
order by newId()
update tableB
set recordOwner = #userFullName
from tableB ptbpd
inner join (
select top (#percentUpdate) percent
id
from tableB
where recordOwner is null
order by newId()
) nd on (ptbpd.id = nd.id)
update #tb_owners
set processed = 1
where userId = #oUserId
end
--there may be some left over, set to last person used
update tableB
set recordOwner = #userFullName
from tableB
where ptbpd.recordOwner is null

How to get multiple repeated using Joins?

I have a temp table with the following structure:
StudentID VALUE
1 5
2 NULL
and need to map the values from it to the table below:
StudentID DEPT
1 1
1 2
2 3
2 4
So the output should be like this:
StudentID DEPT VALUE
1 1 5
1 2 5
2 3 NULL
2 4 NULL
Do I need to use join or merge my table consisits of million record?
I have tried using joins but i am not getting exact what i need?
a JOIN. like this:
SELECT S.StudentId, S.Dept, V.Value
FROM Student AS S
JOIN #TEMP AS V
ON V.StudentId = S.StudentId
ORDER BY V.StudentId
SELECT table2.StudentID
,table2.DEPT
,#TEMP.Value
FROM table2
LEFT JOIN #TEMP
ON table2.StudentID = #TEMP.StudentID

Resources