SQL-запрос для расчета веса или распределения веса на основе значения / ноль - PullRequest
0 голосов
/ 17 декабря 2009

У меня есть таблица со столбцами - id, x1, x2, x3, x4

если у меня есть значения

1,y,y,y,y
2,y,null,n,null
3,y,null,null,null

тогда скажите, я хочу вычислить (1) / (количество у) и отображать строки как

1,.25,.25,.25,.25
2,1,0,0,0
3,1,0,0,0

Возможно ли это сделать с помощью SQL-запроса?

Ответы [ 4 ]

1 голос
/ 18 декабря 2009

Попробуйте это

Пример данных

declare  @t table( Id int,Col1 char(1) null,Col2 char(1) null,Col3 char(1) null,Col4 char(1) null)
INSERT @t select 1, 'Y', 'Y', 'Y', 'Y' union all select 2, 'Y', null, null, null
 union all select 3, 'Y', null, null, null  

Запрос:

select t.id 
 ,case Col1 when 'Y' then LEFT(cast( 1.0/x.cntys as varchar(20)),4) else cast( 0 as varchar(1)) end x1
 ,case Col2 when 'Y' then LEFT(cast( 1.0/x.cntys as varchar(20)),4) else cast( 0 as varchar(1)) end x2
 ,case Col3 when 'Y' then LEFT(cast( 1.0/x.cntys as varchar(20)),4) else cast( 0 as varchar(1)) end x3
 ,case Col4 when 'Y' then LEFT(cast( 1.0/x.cntys as varchar(20)),4) else cast( 0 as varchar(1)) end x4

 from @t t
 join(
 select ROW_NUMBER() over(order by getdate()) rn, 
  COUNT(col1) + COUNT(col2) + COUNT(col3) + COUNT(col4) cntys from @t 
group by id)X
on t.Id = X.rn 

Выход:

id x1 x2 x3 x4 
1 0.25 0.25 0.25 0.25 
2 1.00 0 0 0 
3 1.00 0 0 0 
1 голос
/ 17 декабря 2009

попробуйте следующий

select 

(SUM(case when x1 is null then 0 else 1 end))* 1.0/ ((SUM(case when x1 is null then 0 else 1 end) + SUM(case when x2 is null then 0 else 1 end)+ SUM(case when x3 is null then 0 else 1 end) + + SUM(case when x4 is null then 0 else 1 end)) * 1.0),
(SUM(case when x2 is null then 0 else 1 end))* 1.0/ ((SUM(case when x1 is null then 0 else 1 end) + SUM(case when x2 is null then 0 else 1 end)+ SUM(case when x3 is null then 0 else 1 end) + + SUM(case when x4 is null then 0 else 1 end)) * 1.0),
(SUM(case when x3 is null then 0 else 1 end))* 1.0/ ((SUM(case when x1 is null then 0 else 1 end) + SUM(case when x2 is null then 0 else 1 end)+ SUM(case when x3 is null then 0 else 1 end) + + SUM(case when x4 is null then 0 else 1 end)) * 1.0),
(SUM(case when x4 is null then 0 else 1 end))* 1.0/ ((SUM(case when x1 is null then 0 else 1 end) + SUM(case when x2 is null then 0 else 1 end)+ SUM(case when x3 is null then 0 else 1 end) + + SUM(case when x4 is null then 0 else 1 end)) * 1.0)
from table group by id

вы могли бы убедиться, что не делите на ноль

Редактировать 2

, добавив еще один случай к знаменателю, когда 0, а затем 1. также вы должны изменить

   case when x1 is null then 0 else 1 end

до

 case when x1 = 'y' then 1 else 0 end
1 голос
/ 17 декабря 2009

Вот еще одна атака грубой силой с использованием подзапроса. Настройка некоторых тестовых данных:

CREATE TABLE MyTable
 (
   Id   int     not null
  ,Col1 char(1) null
  ,Col2 char(1) null
  ,Col3 char(1) null
  ,Col4 char(1) null
 )

INSERT MyTable
           select 1, 'Y', 'Y', 'Y', 'Y'
 union all select 2, 'Y', null, 'N', null
 union all select 3, 'Y', null, null, null
 union all select 4, null, null, null, null

Я использовал символьные данные для целевого значения, но у вас не должно возникнуть проблем с его преобразованием в числовое значение. Я добавил четвертую строку, чтобы проверить деление на нули (спасибо ps!). Таким образом,

SELECT
   mt.ID
  ,case mt.Col1 when 'Y' then xx.distrib else 0 end
  ,case mt.Col2 when 'Y' then xx.distrib else 0 end
  ,case mt.Col3 when 'Y' then xx.distrib else 0 end
  ,case mt.Col4 when 'Y' then xx.distrib else 0 end
 from MyTable mt
  inner join (select
                ID
                ,1.0 / (  case Col1 when 'Y' then 1 else 0 end
                        + case Col2 when 'Y' then 1 else 0 end
                        + case Col3 when 'Y' then 1 else 0 end
                        + case Col4 when 'Y' then 1 else 0 end) distrib
               from MyTable) xx
   on xx.Id = mt.Id

появляется для получения желаемых результатов. (Запустите подзапрос самостоятельно, и вы получите деление на ноль ... но я, честно говоря, понятия не имею, почему выполнение всего запроса не выполняется.

1 голос
/ 17 декабря 2009

Наивная версия здесь будет

SELECT 
    id,
    CASE 
    WHEN x1 IS NULL THEN
        0
    WHEN f_eval(x1) + f_eval(x2,0) + f_eval(x3,0) + f_eval(x4,0) = 0 THEN
        -- default value
    ELSE
        1 / (f_eval(x1) + f_eval(x2,0) + f_eval(x3,0) + f_eval(x4,0))
    END,
    -- repeat for each column
FROM
    Table

где f_eval определяется как более или менее следующее:

CREATE FUNCTION f_eval(
      @x_value varchar(1)
BEGIN

    DECLARE @return_val int
    SELECT
        @return_val = 
        case
        WHEN ISNULL(@x_value, 'n') = 'y' THEN
            1
        ELSE
            0
        END

     RETURN @return_val
END
...