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

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

Related

how can extract one row having not null values from a few of rows

for example
tableA has
id
condition_A
condition_B
condition_C
condition_D
AA
NULL
NULL
10
NULL
AA
15
NULL
NULL
NULL
AA
NULL
NULL
10
5
AA
NULL
20
NULL
NULL
AA
NULL
20
NULL
5
every condition has same value with same id
then i want to extract result like
id
condition_A
condition_B
condition_C
condition_D
AA
15
20
10
5
how can extract without null and only one rows?
Thank you :)
select max(condition_A), max(condition_B), max(Condition_C), max(Condition_D)
from tableA where id = 'AA'

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.

SAS: Need to count number of instances per id

Let's assume I have table1:
id value1 value2 value3
1 z null null
1 z null null
1 null y null
1 null null x
2 null y null
2 z null null
3 null y null
3 null null null
3 z null null
id value1 value2 value3
1 z null null
1 z null null
1 null y null
1 null null x
2 null y null
2 z null null
3 null y null
3 null null null
3 z null null
and I have table2:
id
1
2
3
I want to count number of values in each column per id to have output like this. (ex. id 1 has 2 - z's, one y and one x)
id value1 value2 value3
1 2 1 1
2 1 1 0
3 1 1 0
Need to do this in SAS. There is an example of this in Oracle but not in SAS.
If I understand correctly, this is a simple query using proc sql. For all the ids in the first table:
proc sql;
select id, count(val1) as val1, count(val2) as val2, count(val3 as val3)
from table1
group by id;
run;
count() counts the number of non-NULL values in a column or expression.

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;

SQL nested loops

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