2013-11-14 3 views
0

Привет, ребята, у меня есть данные ниже образца, которые я хочу запросить.Подсчет, если данные существуют в строке

MemberID   AGEQ1  AGEQ2  AGEQ2 
----------------------------------------------------------------- 
1217    2   null  null   
58458    3   2   null    
58459    null  null  null    
58457    null  5   null    
299576    6   5   7 

Что мне нужно сделать, это для поиска в таблице, и если AGEX COLUMN содержит какие-либо данные, то он подсчитывает количество раз, есть данные для этой строки в каждом столбце

Результаты Пример:

для MemberId 1217 счетчик будет 1

для MemberId 58458 счетчик будет 2

для MemberId 58459 отсчет будет 0 или нуль

для MemberID 58457 счетчик будет 1

для MemberID 299576 счетчик будет 3

Вот как это должно выглядеть в SQL, если я запросить всю таблицу

1 Дети - 2

2 детей - 1

3 детей - 1

0 Дети - 1

До сих пор я делал это, используя следующий запрос, который не очень эффективен и дает неправильные подсчеты, поскольку существует несколько комбинаций, которые люди могут ответить на вопрос ВОЗРАСТ. Кроме того, я должен написать несколько запросов и изменить это значение NULL не равно нулю в зависимости от того, сколько детей я ищу, чтобы посчитать человека имеет

select COUNT (*) as '1 Children' from Member 
where AGEQ1 is not null 
and AGEQ2 is null 
and AGEQ3 is null 

Этот запрос только дает мне ответ на 1, но я хочу иметь возможность рассчитывать на другие столбцы данных, а также

Надеются, что это красиво и ясно, и спасибо заранее

+1

Сколько 'AGEx' столбцов у вас есть? Это исправлено? И как это может быть как mysql, так и sql-сервер? – unlimit

+0

Извините, что изменили У меня есть 6, но я только показал 3 в качестве примера, но его тот же принцип, я не хочу делать несколько запросов для каждой комбинации. – InvokeIT

ответ

2

Если все столбцы представляют собой целые числа, вы можете воспользоваться целочисленной математикой - делениями столбца, сам будет давать 1, если значение не равно NULL, и в этом случае COALESCE может преобразовать полученный NULL в 0.

SELECT 
    MemberID, 
    COALESCE(AGEQ1/AGEQ1, 0) 
    + COALESCE(AGEQ2/AGEQ2, 0) 
    + COALESCE(AGEQ3/AGEQ3, 0) 
    + COALESCE(AGEQ4/AGEQ4, 0) 
    + COALESCE(AGEQ5/AGEQ5, 0) 
    + COALESCE(AGEQ6/AGEQ6, 0) 
FROM dbo.table_name; 

Чтобы получить количество людей с каждым кол детей, а затем:

;WITH y(y) AS 
(
    SELECT TOP (7) rn = ROW_NUMBER() OVER 
    (ORDER BY [object_id]) - 1 FROM sys.objects 
), 
x AS 
( 
    SELECT 
    MemberID, 
    x = COALESCE(AGEQ1/AGEQ1, 0) 
     + COALESCE(AGEQ2/AGEQ2, 0) 
     + COALESCE(AGEQ3/AGEQ3, 0) 
     + COALESCE(AGEQ4/AGEQ4, 0) 
     + COALESCE(AGEQ5/AGEQ5, 0) 
     + COALESCE(AGEQ6/AGEQ6, 0) 
    FROM dbo.table_name 
) 
SELECT 
    NumberOfChildren = y.y, 
    NumberOfPeopleWithThatMany = COUNT(x.x) 
FROM y LEFT OUTER JOIN x ON y.y = x.x 
GROUP BY y.y ORDER BY y.y; 
+1

О, боже, это сложно ... Я бы придерживался утверждения дела в другой ответ, если вы хотите, чтобы будущие разработчики понимали, что происходит :) –

+1

Где сложная часть? Отдел или дополнение? – billinkc

+0

Отлично, это также дает мне похожие результаты для другого ответа, но как я получу ВСЕГО из людей, у которых есть 1 ребенок или 2 ребенка и т. Д.? – InvokeIT

1

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

select id, a+b+c+d+e+f 
    from (select id, 
       case when age1 is null then 0 else 1 end a, 
       case when age2 is null then 0 else 1 end b, 
       case when age3 is null then 0 else 1 end c, 
       case when age4 is null then 0 else 1 end d, 
       case when age5 is null then 0 else 1 end e, 
       case when age6 is null then 0 else 1 end f 
      from ages 
     ) as t 

Смотрите здесь скрипку http://sqlfiddle.com/#!3/88020/1

Чтобы получить количество лиц с детьми

select childs, count(*) as ct 
    from (
     select id, a+b+c+d+e+f childs 
      from 
       (
       select 
         id, 
         case when age1 is null then 0 else 1 end a, 
         case when age2 is null then 0 else 1 end b, 
         case when age3 is null then 0 else 1 end c, 
         case when age4 is null then 0 else 1 end d, 
         case when age5 is null then 0 else 1 end e, 
         case when age6 is null then 0 else 1 end f 
        from ages) as t 
       ) ct 
    group by childs 
    order by 1 

Посмотри здесь скрипку http://sqlfiddle.com/#!3/88020/24

+0

похоже, что это может сработать, но как я смогу получить общий счет. например, TOTAL количество людей, которые имеют 1 ребенка, 2 детей и т. Д. – InvokeIT

+0

Отредактировал свой ответ тем, что вы просили. –

+0

Ваш ответ был намного понятнее, а также работает и намного проще, но мне жаль, что я уже принял приведенный выше ответ, который также верен. – InvokeIT

1

Я хотел бы посмотреть на использование UNPIVOT. Это сделает вашу широкую колонку в ряд.Поскольку вы не заботитесь о том, какое значение было в столбце, просто наличие/отсутствие значения, это приведет к созданию строки для столбца, отличного от нуля.

Трюк затем превращается в желаемый выходной формат. Вероятно, это было сделано более чистым, но я поклонник «показывать свою работу», чтобы другие могли удовлетворить его потребности.

SQLFiddle

-- Using the above logic 
WITH HadAges AS 
(
    -- Find everyone and determine number of rows 
    SELECT 
     UP.MemberID 
    , count(1) AS rc 
    FROM 
     dbo.Member AS M 
     UNPIVOT 
     (
     ColumnValue for ColumnName in (AGEQ1, AGEQ2, AGEQ3) 
     ) AS UP 
    GROUP BY 
     UP.MemberID 
) 
, NoAge AS 
(
    -- Account for those that didn't show up 
    SELECT M.MemberID 
    FROM 
     dbo.Member AS M 
    EXCEPT 
    SELECT 
     H.MemberID 
    FROM 
     HadAges AS H 
) 
, NUMBERS AS 
(
    -- Allowable range is 1-6 
    SELECT TOP 6 
     ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS TheCount 
    FROM 
     sys.all_columns AS SC 
) 
, COMBINATION AS 
(
    -- Link those with rows to their count 
    SELECT 
     N.TheCount AS ChildCount 
    , H.MemberID 
    FROM 
     NUMBERS AS N 
     LEFT OUTER JOIN 
      HadAges AS H 
      ON H.rc = N.TheCount 
    UNION ALL 
    -- Deal with the unlinked 
    SELECT 
     0 
    , NA.MemberID 
    FROM 
     NoAge AS NA 
) 
SELECT 
    C.ChildCount 
, COUNT(C.MemberID) AS Instances 
FROM 
    COMBINATION AS C 
GROUP BY 
    C.ChildCount; 
Смежные вопросы