I have a table that has the following columns:
NAME (VARCHAR)
FISHING (INT)
SAILING (INT)
NAVIGATION (INT)
SALARY (NUMERIC)
This table has 9 rows of data. I used ALTER to add a column that would hold the rank of the person's salary. It is called SALARY_RANK. My idea was to populate that column with a SELECT statement that would fill that rank. I tried to use INSERT with the below SELECT statement to fill that column but it ends up creating 9 new rows where all except the new column are NULL.
What is the best way to go about this?
This is the SQL I have written for the new column:
ALTER TABLE #CODY_CREW
ADD SALARY_RANK INT;
INSERT INTO #CODY_CREW (SALARY_RANK)
SELECT
DENSE_RANK() OVER (ORDER BY SALARY) AS 'SALARY_RANK'
FROM #CODY_CREW
This is what happens when I run that:
NAME FISHING SAILING NAVIGATION SALARY SALARY_RANK
-------------------------------------------------- ----------- ----------- ----------- --------------------------------------- -----------
Amy 3 5 1 46000 NULL
Bill 1 2 5 43000 NULL
Carl 3 4 2 47000 NULL
Dan 4 3 1 36000 NULL
Eva 4 2 2 43000 NULL
Fred 1 3 4 55000 NULL
Greg 3 1 5 68000 NULL
Henry 5 4 2 64000 NULL
Ida 3 3 3 60000 NULL
NULL NULL NULL NULL NULL 1
NULL NULL NULL NULL NULL 2
NULL NULL NULL NULL NULL 2
NULL NULL NULL NULL NULL 3
NULL NULL NULL NULL NULL 4
NULL NULL NULL NULL NULL 5
NULL NULL NULL NULL NULL 6
NULL NULL NULL NULL NULL 7
NULL NULL NULL NULL NULL 8
(18 rows affected)
You should be using UPDATE instead of INSERT query. Try like below.
UPDATE C1
SET C1.SALARY_RANK = C2.SALARY_RANK
FROM #CODY_CREW C1
JOIN (SELECT
DENSE_RANK() OVER (ORDER BY SALARY) AS 'SALARY_RANK', Name
FROM #CODY_CREW) C2
ON C1.Name = C2.Name
In SQL Server, you can use an updatable CTE or subquery:
WITH toupdate AS (
SELECT cc.*, DENSE_RANK() OVER (ORDER BY SALARY) AS NEW_SALARY_RANK
FROM #CODY_CREW cc
)
UPDATE toupdate
SET SALARY_RANK = NEW_SALARY_RANK;
A JOIN is not necessary.
Related
The following table consists of the columns EmployeeID, JobNum, CompDate.
Basically there are 3 different employees that have certain job ids and their completed date time associated with them. There are some jobNum that have no association to a particular EmployeeID and may have a complete date.
Problem:
1) Remove the records for a EmployeeID when the Complete date is not null or is populated with date.
2) Delete the record that has null values for both columns JobNum and CompDate for an Employee WHEN there is a record for that EmployeeID that consists of an open job (when JobNum is NOT NULL and CompDate is NULL). THIS IS FOR DUPLICATES.
Tried using ranking function with case statements. Does not rank properly.
[JobNum],
[CompDate],
RANK ( ) OVER( PARTITION BY [EmployeeID] ORDER BY
CASE WHEN ([JobNum] is null AND [CompDate] is null) THEN 1
WHEN ([JobNum] is not null AND [CompDate] is null) THEN 2
WHEN ([JobNum] is not null AND [CompDate] is not null) THEN 3
END ASC) as Rank
FROM [dbo].test1
WHERE [EmployeeID] IN (SELECT [EmployeeID] FROM dbo.test1
GROUP BY [EmployeeID]
HAVING COUNT(*) > 1)
EmployeeID JobNum CompDate Rank
1 NULL NULL 1
1 401 NULL 2
1 435 NULL 2
1 358 2019-07-15 15:10:57.810 4
2 285 NULL 1
2 299 2019-07-15 15:14:04.603 2
2 305 2019-07-14 15:10:57.810 2
2 330 2019-06-13 10:10:30.710 2
3 NULL NULL 1
3 435 NULL 2
3 402 2019-07-11 13:10:47.610 3
Ex:
EmployeeID JobNum CompDate Rank
Delete this -> 1 NULL NULL 1
when this exists -> 1 401 NULL 2
when this exists -> 1 435 NULL 2
1 358 2019-07-15 15:10:57.810 4
You seem to want only rows where compdate is null and one of the following two conditions:
jobnum is null
jobnum is not null and no rows for the employee have jobnum as null
I'm not sure what rank() has to do with these filtering conditions:
select t.*
from test1 t
where t.compdate is not null and -- condition 1
(t.jobnum is null or
not exists (select 1
from test1 tt
where tt.employeeid = t.employeeid and
tt.compdate is null and
tt.jobnum is null
)
);
I want to compare the values from a table where there are null and not null values for the same ID ( If not null then I want minimum of two not null values). IF all the values are null for the given ID, I want the values to be displayed as null for the ID.
Input
ID Amount
1 Null
1 Null
1 Null
1 500
1 600
1 700
2 Null
2 Null
2 Null
2 Null
2 Null
3 Null
3 Null
3 300
3 600
3 200
Expected output
ID Amount
1 500 (min Not null value)
2 Null
3 200 (Min Not null value)
Simple grouping will do the trick:
select t.id, min(t.amount)
from table t
group by t.id
Simply I have two tables ForecastBackup,ForecastTotal
I want to select 4 columns from ForecasTotal table and insert into ForecastBackup
for example
ForecastTotal
UCPVol UCPVal IBNSINAVol IBNSINAVal
1 1 NULL NULL
2 3 NULL NULL
NULL NULL 1 4
NULL NULL 3 5
NULL NULL 1 6
I want to insert into ForecastBackup non null values
I mean result should be
UCPVol UCPVal IBNSINAVol IBNSINAVal
1 1 1 4
2 3 3 5
NULL NULL 1 6
I used this SQL command but doesn't work
INSERT INTO
ForecastBackup (UCPVol,UCPVal,IBNSINAVol,IBNSINAVal)
SELECT (select UCPVol,UCPVal from ForecastTotal where UCPVol is not null),
(select IBNSINAVol,IBNSINAVal from ForecastTotal where IBNSINAVal is not null)
from ForecastTotal
Is this possible ?
From your input and out I think you need this query
INSERT INTO ForecastBackup (UCPVol,UCPVal, IBNSINAVol, IBNSINAVal)
SELECT
A.UCPVol, A.UCPVal, B.IBNSINAVol, B.IBNSINAVal
FROM
ForecastTotal A
LEFT JOIN
ForecastTotal B ON A.UCPVal = B.IBNSINAVol
Try this syntax:
INSERT INTO column_1 ( val_1, val_from_other_table )
VALUES('val_1', (SELECT val_2 FROM table_2 WHERE val_2 = something))
currently i have following table structure in sql server2008 r2
tbusertable
userid username uid status
1 abc null null
2 yax null null
3 xcd null null
4 max null null
5 wax null null
6 ear null null
7 yes null null
8 sqt null null
9 ora null null
tbphtable
pid userid phnos
1 1 456
2 2 456
3 3 4568
4 4 789
5 5 5555
6 6 4599
7 7 456
8 8 111
9 9 111
tbeidtable
eid userid eid
1 1 y#gmail.com
2 2 abd#gmail.com
3 3 erer#gmail.com
4 4 yer#gmail.com
5 5 g#gmail.com
6 6 g#gmail.com
i want to update uid column of tbusertable table with unique id, if they have same phnos for eid without cursor because table have large records and cursor take long time to run
desire output
userid 1,2,7 have same phnos so they have same unique id and similarly
userid 5,6 have same eid so they have different unique id
and similarly userid 8,9 have same phnos so they have same different unique id
tbusertable
userid username uid status
1 abc D7CCBC4E-EEE6-4AC8-806D-A04DCC77DF54 null
2 yax D7CCBC4E-EEE6-4AC8-806D-A04DCC77DF54 null
3 xcd null null
4 max 0608CFF7-3FC6-4952-91AE-5E42D6558827 null
5 wax 0608CFF7-3FC6-4952-91AE-5E42D6558827 null
6 ear null null
7 yes D7CCBC4E-EEE6-4AC8-806D-A04DCC77DF54 null
8 sqt 5823E1FD-2AF3-4BA7-8C48-946A16E0D3E2 null
9 ora 5823E1FD-2AF3-4BA7-8C48-946A16E0D3E2 null
If I understand correctly, you can calculate the new ids for each phone number using a subquery and then use this for the update:
update u
set uid = pp.new_uid
from tbusertable u join
tbphtable p
on u.userid = p.userid join
(select phnos, newid() as new_uid
from tbphtable
group by phnos
) pp
on p.phnos = pp.phnos;
EDIT:
Because of how SQL Server optimizes queries, you might need to put the newids in a temporary table:
select phnos, newid() as new_uid
into #pp
from tbphtable
group by phnos;
And then:
update u
set uid = pp.new_uid
from tbusertable u join
tbphtable p
on u.userid = p.userid join
#pp pp
on p.phnos = pp.phnos;
SQL Server can rewrite queries, resulting in functions being called more commonly than expected. Putting the values in a temporary table should solve that problem.
I have a problem, I have added a column to one of my database tables and now i need to populate this column with data.
Here are the tables:
Table QUESTIONNAIRE_QUESTIONS
with columns:
ID,
QUESTION_NUMBER,
PARENT_QUESTION_ID,
PARENT_QUESTIONNAIRE_ID,
QUESTION_CODE
Table QUESTIONNAIRE
with columns:
ID,
INTRODUCTION
What I first need to do is to find all unique QUESTIONNAIRE.ID and for each of those I need to find all QUESTIONNAIRE_QUESTIONS.ID that have this id as PARENT_QUESTIONNAIRE_ID and set the QUESTION_CODE as QUESTION_CODE=QUESTION_NUMBER*100.
Then, before moving on to the next QUESTIONNAIRE_ID i need to find all QUESTIONNAIRE_QUESTIONS.ID that have the current QUESTIONNAIRE_QUESTIONS.ID as PARENT_QUESTION_ID and set the QUESTION_CODE as
QUESTION_CODE=(parents question_code)+'.'+QUESTION_CODE.QUESTION_NUMBER*100.
How to perform this, complicated, nested loop? Seems like I have to use several loops?
Sample Data:
QUESTIONNAIRES
ID
1869359
1876176
QUESTIONNAIRE_QUESTIONS
ID QUESTION_NUMBER PARENT_QUESTIONNAIRE_ID PARENT_QUESTION_ID QUESTION_CODE
1869360 1 1869359 null null
1869362 2 1869359 null null
1869364 3 1869359 null null
1869367 1 null 1869364 null
1869369 1 1876176 null null
1869371 2 1876176 null null
1869372 3 1876176 null null
1869374 4 1876176 null null
1869377 1 null 1869372 null
And after i want it to look like this:
QUESTIONNAIRE_QUESTIONS
ID QUESTION_NUMBER PARENT_QUESTIONNAIRE_ID PARENT_QUESTION_ID QUESTION_CODE
1869360 1 1869359 null 100
1869362 2 1869359 null 200
1869364 3 1869359 null 300
1869367 1 null 1869364 300.100
1869368 1 null 1869367 300.100.100
1869369 2 null 1869367 300.100.200
1869370 1 1876176 null 100
1869371 2 1876176 null 200
1869372 3 1876176 null 300
1869374 4 1876176 null 400
1869377 1 null 1869371 200.100
Note that it can be more levels of "child questions"
Thanks!
UPDATE QUESTIONNAIRE_QUESTIONS
SET QUESTION_CODE = (QUESTION_NUMBER * 100)
WHERE QUESTIONNAIRE_QUESTIONS.ID IN (SELECT DISTINCT QUESTIONNAIRE.ID
FROM QUESTIONNAIRE, QUESTIONNAIRE_QUESTIONS
WHERE QUESTIONNAIRE_QUESTIONS.ID = PARENT_QUESTION_ID)
Not so sure about the 2nd question. Is that a typo?QUESTION_CODE.QUESTION_NUMBER*100