SQL merge and sum multiple rows into one - sql

Essentially I have a SQL table that looks like this;
Name Week 1 Week 2 Week 3 Week 4 Week 5
James NULL 5 NULL NULL NULL
James 10 NULL NULL NULL NULL
James NULL NULL NULL 5 NULL
James NULL NULL NULL 20 NULL
Tom NULL NULL 5 NULL NULL
Tom NULL 10 NULL NULL NULL
Tom 25 NULL NULL NULL NULL
Tom NULL NULL NULL 5 NULL
Tom NULL NULL NULL 5 NULL
And I would want to combine together the rows (while also summing the values) to get something more like this;
Name Week 1 Week 2 Week 3 Week 4 Week 5
James 10 5 20 25 NULL
Tom 25 10 5 10 NULL
But I can't think of a good way of doing so. My data has quite the number of columns and rows so I'm looking for something which ideally doesn't require listing out all the individual column or row names.
Thanks

Just Sum the Rows and Group by name
select
Name
, Week1 = sum(Week 1)
, Week2 = sum(Week 2)
, Week3 = sum(Week 3)
, Week4 = sum(Week 4)
, Week5 = sum(Week 5)
from Table
group by Name

Related

check data sequence in SQL

I have weekly data in columns. I need to exclude records where there are continuous null values for four week.
TempID
Week1
Week 2
Week3
Week4
Week5
Week6
Week7
123
1
NULL
NULL
NULL
NULL
4
4
234
3
5
5
6
NULL
4
4
333
4
NULL
4
8
NULL
4
4
For this example I need to exclude temp id 123.
And rest need to be included.Basically exclude records where there is four continuous null records in columns.
How I can check the order I described here?
You may just repeat all the possible sequences in the where condition wrapped withcoalesce function: coalesce returns first non-null value, so if it returns null, then all the values are null.
select *
from yourtable
where coalesce(week1, week2, week3, week4) is null
or coalesce(week2, week3, week4, week5) is null
or coalesce(week3, week4, week5 week6) is null
or coalesce(week4, week5 week6 week7) is null
Since you are dealing with four columns out of seven, there are really only 4 combinations to test for:
Select * from table
Where
(week1 is null and week2 is null and week3 is null and week4 is null)
Or
(week2 is null and week3 is null and week4 is null and week5 is null)
Or
(week3 is null and week4 is null and week5 is null and week6 is null)
Or
(week4 is null and week5 is null and week6 is null and week7 is null)

INSERT a RANK into a SQL table

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.

Compare the column values where there are null and not null values

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

SQL Server 2012 multiple joins technique

I have appended a series of columns (11 of them) to the end my data that each act as a flag.
Here is a sample of these categories:
(Notice that multiple flags can appear for a single row!)
cat2 cat3 cat4 cat5 cat6 cat7 cat8 cat9 cat10 cat11 cat12
NULL 1 NULL NULL 2 NULL NULL 1 NULL NULL NULL
NULL NULL NULL NULL NULL NULL 2 NULL NULL NULL NULL
NULL NULL NULL 1 1 NULL NULL NULL NULL NULL NULL
NULL 1 1 NULL NULL NULL NULL NULL NULL NULL NULL
3 NULL NULL NULL NULL NULL 2 NULL NULL NULL NULL
I have a separate table that pairs each flag with a description string.
ref_id category_position description
------------------------------------------------
1 2 string description 1
2 2 string description 2
3 2 string description 3
1 3 string description 4
1 4 string description 5
1 5 string description 6
1 6 string description 7
2 6 string description 8
1 7 string description 9
1 8 string description 10
2 8 string description 11
1 9 string description 12
1 10 string description 13
1 11 string description 14
1 12 string description 15
I want to somehow join my string description against every category that is not null, so that my categories are 'human readable' and defined.
Here is a possible outcome that would be acceptable to me, based on the first row of sample data (including the header):
cat3 [join description] cat6 [join description] cat9 [join description]
1 string description 4 2 string description 8 1 string description 12
Trouble is - I don't know how to do this multi-part join. I don't want to join 12 times as this seems sloppy and perhaps won't work for the millions of rows I'm operating on.
Here's the function alternative... which isn't going to be faster than doing the joins but is useful in limited use.
create function dbo.returnDesc (#ref_id int)
returns varchar (256)
as
begin
declare #return varchar(256)
set #return = (select [description] from yourTable where ref_id = #ref_id)
return #return
end
Then in use....
select
....
dbo.returnDesc(cat2),
dbo.returnDesc(cat3),
dbo.returnDesc(cat4),
....
from
YourMainTable

How to use group by with null values

I have a SQL query which results as
personCount toatlMinute Meal QPWaiting NoOfCR CRNo
0 2 NULL NULL NULL NULL
1 7 NULL NULL NULL NULL
2 8 NULL NULL NULL NULL
3 16 NULL NULL NULL NULL
4 128 NULL NULL NULL NULL
0 NULL NULL 14 2 5555, 6666
3 NULL NULL NULL NULL NULL
4 NULL NULL NULL NULL NULL
2 NULL NULL 14 2 5555, 6666
3 NULL NULL 14 2 5555, 6666
4 NULL NULL 14 2 5555, 6666
0 NULL 2 NULL NULL NULL
Now I want to use group by 1st column (personcount) and want to sum 2nd and 3rd column
but don't want to sum 4th, 5th and 6th column. But output should show all data in one for unique person count.
SELECT
personCount,
SUM(toatlMinute) toatlMinute,
SUM(Meal) Meal,
QPWaiting,
NoOfNCR AS NoOfCR,
NCRNo AS CRNo
FROM
#OperatorData
GROUP BY
personCount, QPWaiting, NoOfNCR, NCRNo
and it gives output as
personCount toatlMinute Meal QPWaiting NoOfCR CRNo
0 2 2 NULL NULL NULL
0 NULL NULL 14 2 5555, 6666
1 7 NULL NULL NULL NULL
2 8 NULL NULL NULL NULL
2 NULL NULL 14 2 5555, 6666
3 16 NULL NULL NULL NULL
3 NULL NULL 14 2 5555, 6666
4 128 NULL NULL NULL NULL
4 NULL NULL 14 2 5555, 6666
A you can see there are two rows for 0 person count. However I want only one row.
How can get this output? Kindly advise
If you want to get values from the last three columns, so the NULL values go away, then use max() or min():
SELECT personCount, SUM(toatlMinute) as toatlMinute, SUM(Meal) as Meal,
max(QPWaiting) as QPWaiting, max(NoOfNCR) AS NoOfCR, max(NCRNo) AS CRNo
FROM #OperatorData
GROUP BY personCount;