Merging of rows based on data - sql

In my application I am using SQL Server. The output of one of the queries is:
Name countA countB countC countD countE countF
Name1 NULL NULL 1 NULL NULL NULL
Name2 NULL NULL 1 NULL NULL NULL
Name2 NULL NULL NULL NULL NULL 1
Name3 NULL NULL NULL NULL NULL 1
Name3 NULL NULL 6 NULL NULL NULL
I am expecting the output to be a single row representing the count data as is shown below.
Name countA countB countC countD countE countF
Name1 NULL NULL 1 NULL NULL NULL
Name2 NULL NULL 1 NULL NULL 1
Name3 NULL NULL 6 NULL NULL 1
What do I need to change to fix this query?

Looking at the data, you should just be able to apply a GROUP BY to the query based on Name, and apply a SUM aggregate to countA, countB, etc.

Related

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

Group multiple rows together

I have a table which contains the following and I am looking to group them to get the below output. Is it possible?
Input
ID Value1 Value2 Value3
5 Y NULL NULL
5 NULL 1 NULL
5 NULL NULL USA
5 NULL NULL NULL
6 N NULL NULL
6 NULL 2 NULL
6 NULL NULL GBP
6 NULL NULL NULL
Output
ID Value1 Value2 Value3
5 Y 1 USA
6 N 2 GBP
Group by the id and use max() to get the non-null value per each group
select id,
max(value1) as value1,
max(value2) as value2,
max(value3) as value3
from your_table
group by id
BTW you should think about changing you table design. It is not normalized.

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;

How do use one value in a table to replace another value in the same table?

I have a table that contains codes (i.e. 8202-6) and has a resulting value in a different column. I used the "Case When" function to take the codes out a single column and place them in separate columns based on the code number. However, now I end up with a bunch of null values in the rows and one code with one result. I would like to replace the actual code with it's corresponding value (i.e. 8206-6 = Height, result 75). So in the Height column I get the LOINC code instead of the Height value of 75. Can anyone help me figure out the right code to use. Below is an example of the code that I'm using just to get the columns separated.
Select Distinct
p.PatientID,
Convert(varchar, fs.obsdate, 101) as Date_of_Service,
p.LASTNAME,
p.FIRSTNAME,
CONVERT(varchar, "p"."DATEOFBIRTH", 101) as DOB,
Case When fs.loinccode='8302-2' Then fs.loinccode end as Height,
Case When fs.loinccode='3141-9' Then fs.loinccode end as Weight,
Case When fs.loinccode='8310-5' Then fs.loinccode end as Temperature,
Case When fs.loinccode='8287-5' Then fs.loinccode end as HeadCircumf,
Case When fs.loinccode='8867-4' Then fs.loinccode end as Pulse,
Case When fs.loinccode='9279-1' Then fs.loinccode end as Respiration,
Case When fs.loinccode='8480-6' Then fs.loinccode end as BPSystolic,
Case When fs.loinccode='8462-4' Then fs.loinccode end as BPDiastolic,
fs.obsvalue as Test_Results,
fs.units as Test_Units
From
PERSON as p
Left Outer join flowsheet_observation fs on fs.pid=p.pid
Result:
Height Weight Temperature HeadCircumf Pulse Respiration BPSystolic BPDiastolic Test_Results Test_Units
NULL NULL NULL NULL NULL NULL NULL NULL + history of lef tshoulder dislocation 10 years ago Current Meds: NULL
NULL NULL NULL NULL NULL NULL NULL NULL never NULL
NULL NULL NULL NULL NULL NULL NULL NULL regular NULL
NULL NULL NULL NULL NULL NULL NULL NULL tympanic NULL
NULL NULL NULL NULL NULL NULL NULL 8462-4 100 mm Hg
NULL NULL NULL NULL NULL NULL 8480-6 NULL 140 mm Hg
NULL NULL NULL NULL 8867-4 NULL NULL NULL 82 /min
NULL NULL 8310-5 NULL NULL NULL NULL NULL 99.1 deg F
NULL 3141-9 NULL NULL NULL NULL NULL NULL 283 lb
8302-2 NULL NULL NULL NULL NULL NULL NULL 72.5 in
NULL NULL NULL NULL NULL NULL NULL NULL 37.72 NULL
NULL NULL NULL NULL NULL NULL NULL NULL regular NULL
NULL NULL NULL NULL NULL NULL NULL NULL tympanic NULL
NULL NULL NULL NULL NULL NULL NULL 8462-4 100 mm Hg
NULL NULL NULL NULL NULL NULL 8480-6 NULL 142 mm Hg
NULL NULL NULL NULL 8867-4 NULL NULL NULL 86 /min
NULL NULL 8310-5 NULL NULL NULL NULL NULL 99.4 deg F
NULL 3141-9 NULL NULL NULL NULL NULL NULL 281 lb
Any help with this would be greatly appreciated.
TRY used MAX(CASE WHEN THEN END)
AND group by other fields
You need to create a table code_names which relates the codes with their meaning,
code | label
8302-2 | Height
3141-9 | Weight
...
then join flowsheet_observation with it and select label instead of code. No need for all those cases.
Edit: if creating a table of codes is not an option, the relation of codes can be created with a union:
SELECT '8302-2' AS code, 'Height' AS label
UNION
SELECT '3141-9' AS code, 'Weight' AS label
UNION
...