SQL Server 2008: как получить подробный идентификатор при выполнении нескольких столбцов GROUP BY и HAVING - PullRequest
0 голосов
/ 28 марта 2012

Я посмотрел ответы на подобные вопросы, но мне не удалось перевести подход OVER () / ROWNUMBER () к моей проблеме.

У меня есть таблица, которая содержит следующие столбцы:

CREATE TABLE [dbo].[Problem]( 
    [UniqueId] [int] NOT NULL, 
    [Attribute1] [int] NOT NULL, 
    [Attribute2] [int] NULL, 
    [Attribute3] int NULL, 
    [Attribute4] int NULL, 
    [Attribute5] [money] NULL, 
    [Attribute6] [varchar](50) NULL, 
) ON [PRIMARY] 

Проблема состоит в том, чтобы определить процентное содержание случаев, когда «Атрибут6» заполняется для набора строк, когда их больше, чем1 значение для «Attribute5», когда «Attibute1» - «Attribute4» были одинаковыми.Моим первым шагом было получить делитель (примерный кадр), который, как мне кажется, запечатлен с помощью следующего кода (включенного, чтобы вы могли видеть мое мышление):

SELECT SUM(Number)  AS Divisor
FROM    (
        SELECT Attribute1, Attribute2, Attribute3, Attribute4, COUNT(*) AS Number
        FROM    (
                SELECT Attribute1, Attribute2, Attribute3, Attribute4, Attribute5
                FROM dbo.Problem
                GROUP BY Attribute1, Attribute2, Attribute3, Attribute4, Attribute5
                ) AS levelOne
        GROUP BY Attribute1, Attribute2, Attribute3, Attribute4
        HAVING COUNT(*) > 1
        ) AS levelTwo

Затем я получаю Дивиденд (считайте где Аттибут 6заполняется в рамке образца).Это представляло проблему, потому что я не мог включить атрибут 6 в GROUP BY, но мне нужно было его изучить.Я применил хак, используя MAX () для включения UniqueId, а затем выполнил самостоятельное СОЕДИНЕНИЕ.Не рад этому подходу.

SELECT SUM(Number)  AS Dividend
FROM    (
        SELECT MAX(UniqueId) AS UniqueId, Attribute1, Attribute2, Attribute3, Attribute4, COUNT(*) AS Number
        FROM    (
                SELECT MAX(UniqueId) AS UniqueId, Attribute1, Attribute2, Attribute3, Attribute4, Attribute5
                FROM dbo.Problem
                GROUP BY Attribute1, Attribute2, Attribute3, Attribute4, Attribute5
                ) AS levelOne
        GROUP BY Attribute1, Attribute2, Attribute3, Attribute4, Attribute5
        HAVING COUNT(*) > 1
        ) AS levelTwo
INNER JOIN dbo.Problem p
    ON p.UniqueId = levelTwo.UniqueId
WHERE p.Attribute6 IS NOT null

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

Вот некоторые примеры данных.

INSERT INTO Problem VALUES (8, 17, 1, 99213, 59.85, 'A')
INSERT INTO Problem VALUES (8, 17, 1, 90658, 12.61, '')
INSERT INTO Problem VALUES (8, 17, 1, 90658, 12.56, '')
INSERT INTO Problem VALUES (8, 17, 1, 87880, 10.51, '')
INSERT INTO Problem VALUES (8, 17, 1, 87880, 4.65, 'A')
INSERT INTO Problem VALUES (8, 17, 2, 99399, 104.57, 'B')
INSERT INTO Problem VALUES (8, 17, 2, 90460, 22.51, '')
INSERT INTO Problem VALUES (8, 17, 2, 90460, 25.54, 'A')
INSERT INTO Problem VALUES (8, 17, 2, 99391, 125.55, 'A')
INSERT INTO Problem VALUES (8, 17, 2, 99391, 104.57, 'B')
INSERT INTO Problem VALUES (8, 17, 2, 99391, 104.57, 'B')
INSERT INTO Problem VALUES (8, 18, 2, 90460, 25.51, 'B')
INSERT INTO Problem VALUES (8, 18, 2, 90744, 25.54, 'B')

В этом наборе из 13 строк ответ составляет 77,78% (7 из 9).Строки 2 + 3 представляют собой группу из 8 - 17 - 1 - 90658 с несколькими значениями для атрибута 5, поэтому является частью выборочного кадра (делителя), но не имеет нескольких значений для атрибута 6, поэтому не является частью ответа (дивиденды).Строки 4 + 5, 7 + 7 и 9 + 10 + 11 соответствуют обоим тестам.Спасибо за вклад!

Ответы [ 2 ]

1 голос
/ 29 марта 2012

SQL легче понять наизнанку.

Проблема состоит в том, чтобы определить процент случаев, когда «Атрибут6» заполняется для набора строк, когда для «Атрибута 5» имеется более 1 значения, когда «Атрибут1» - «Атрибут4» совпадают.

ломается так:

  1. Где атрибуты 1-4 одинаковы
  2. И есть более одного значения для атрибута5
  3. Укажите процентное отношение количества заполненных атрибутов6

Вот так:

select

    attribute1, attribute2, attribute3, attribute4,

    -- 3. give percentage of times Attribute6 is populated
    -- Percentage is numerator * 100 over denominator
    -- 3.a. Numerator: Number of times attribute 6 is populated
    sum( case when attribute6 is null then 0 else 1 end)
    * 100
    / 
    -- 3.b. Denominator: Total number of attribute5 found
    count(attribute5)
from Problem p

-- 1. where attributes 1-4 are the same
group by attribute1, attribute2, attribute3, attribute4
-- 2. And there is more than one value for attribute5
having count(distinct attribute5) > 1

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

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

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

Непонятно, как вы хотите обрабатывать пустые и пустые строки, поэтому я предполагаю, что нулевые и пустые строки не считаются нормальным значением.

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

select
    sum(nDistinct5) as nDemoninator,
    sum(nDistinct6) as nNumerator,

    sum(nDistinct6) 
    * 100.0
    /
    sum(nDistinct5)
from
(
    select

        attribute1, attribute2, attribute3, attribute4,

        -- 3. give percentage of times Attribute6 is populated
        -- Percentage is numerator * 100 over denominator
        -- 3.a. Numerator: Number of times attribute 6 is populated
        count(distinct attribute6) as nDistinct6,
        -- 3.b. Denominator: Total number of attribute5 found
        sum(1) as nDistinct5
    from Problem p

    -- 1. where attributes 1-4 are the same
    group by attribute1, attribute2, attribute3, attribute4
    -- 2. And there is more than one value for attribute5
    having count(distinct attribute5) > 1
) g

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

select 
    p.*, g.nDistinct6, g.nDistinct5
from 
( 
    select 

        attribute1, attribute2, attribute3, attribute4, 

        -- 3. give percentage of times Attribute6 is populated 
        -- Percentage is numerator * 100 over denominator 
        -- 3.a. Numerator: Number of times attribute 6 is populated 
        count(distinct attribute6) as nDistinct6, 
        -- 3.b. Denominator: Total number of attribute5 found 
        sum(1) as nDistinct5 
    from Problem p 

    -- 1. where attributes 1-4 are the same 
    group by attribute1, attribute2, attribute3, attribute4 
    -- 2. And there is more than one value for attribute5 
    having count(distinct attribute5) > 1 
) g

right outer join Problem p
on p.attribute1 = g.attribute1
and p.attribute2 = g.attribute2
and p.attribute3 = g.attribute3
and p.attribute4 = g.attribute4
order by p.attribute1, p.attribute2, p.attribute3, p.attribute4

Здесь отображаются все строки из Problem и итоги соответствующих групп для числа различных Attribute6 и Attribute5, поэтому вы можете проверить, что это действительно те числа, которые вы хотите использовать. Если строк слишком много и вы просто хотите посмотреть несколько сотен глаз, вы можете использовать top

0 голосов
/ 28 марта 2012

Не уверен, что я полностью понимаю ваш вопрос, но я думаю, что вы можете избежать объединения в запросе на дивиденды, добавив Where P.Attribute6 не является нулевым во внутренний запрос (уровень 1)

помогает тебе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...