Since we are in DBMS environment, it is possible to use set-based approach. So, assuming that table has an identifier field (id) - primary key or unique and not null, the job can be done this way:
SELECT numeric_field * count(flag_field) AS not_null_flag_numeric_value_or_zero
FROM my_table
GROUP BY id, numeric_field
If value field is of character data type some char function should be used. So, practical implementation of the approach might be as below:
SELECT * INTO #temporary_table
FROM
(VALUES
(1, 1, 111, 'string_1'),
(2, NULL, 222, 'string_2')
) data_table(id, flag_field, numeric_field, character_field)
ALTER TABLE #temporary_table ADD CONSTRAINT tab_pk PRIMARY KEY (id)
SELECT
count(flag_field) AS is_not_null,
numeric_field * count(flag_field) AS numeric_value_or_zero,
numeric_field * nullif(count(flag_field), 0) AS numeric_value_or_null,
left(character_field, len(character_field) * count(flag_field)) AS character_value_or_empty,
stuff(character_field, nullif(count(flag_field), 0), 0, '') AS character_value_or_null
FROM #temporary_table
GROUP BY id, numeric_field, character_field
--DROP TABLE #temporary_table
Another option to get NOT NULL sign in form of 1 is to use conversion of flag_field value to bit:
... cast(flag_field as bit) ...
This works when conversion to bit is available for your flag_field data type and is usefull when you can consider 0-values and NULLs as same NO VALUE. Represented by NULL or 0 - as you choose:
SELECT
nullif(cast(flag_field as bit), 0) AS is_not_null_or_null,
isnull(cast(flag_field as bit), 0) AS is_not_null_or_zero,
numeric_field * nullif(cast(flag_field as bit), 0) AS value_or_null,
numeric_field * isnull(cast(flag_field as bit), 0) AS value_or_zero
FROM #temporary_table