Унифицированные записи для запроса к базе данных с Sql - PullRequest
1 голос
/ 23 марта 2009

Основная потребность в том, что если запись имеет атрибут «Срочно», то значение атрибута должно отображаться в столбце «Срочно». Если запись имеет значение атрибута «закрыто», то значение атрибута должно отображаться в столбце «Закрыто».

У меня есть запрос ниже. Моя проблема в том, что среди результатов, которые я получаю, есть две записи с одинаковым RequesterID (одна с допустимым значением в столбце «Срочно» и одна со значением в столбце «Закрыто») Моя проблема в том, что мне нужно, чтобы эти две конкретные записи отображались как одна запись.

Есть идеи?

SELECT DISTINCT 
   r.RequesterID,
   sr.ModifiedDate,
   p.FirstName + ' ' + p.LastName AS RequesterName,
   CASE
     WHEN sa.Attribute = 'Urgent' THEN sa.AttributeValue
     ELSE NULL
   END AS Urgent,
   CASE
     WHEN sa.Attribute = 'Closed' THEN sa.AttributeValue 
     ELSE NULL
   END AS Closed
FROM
   Requester AS r 
   INNER JOIN SubRequester AS sr 
     ON r.RequesterID = sr.RequesterID
   INNER JOIN SubRequesterAttribute AS sa
     ON sr.SubRequesterID = sa.SubRequesterID
   CROSS JOIN Personnel AS p
WHERE 
     (r.UserID = p.ContractorID
     OR r.UserID = p.EmployeeID)
   AND 
     (sa.Attribute IN ('Urgent', 'Closed'))
GROUP BY r.RequesterID, sr.ModifiedDate, p.FirstName, p.LastName, 
   sa.Attribute, sa.AttributeValue

Ответы [ 2 ]

3 голосов
/ 23 марта 2009

Вам нужно будет дважды присоединиться к вашей таблице атрибутов подчиненного запросчика. Один с атрибутом Срочный и один с атрибутом Закрыть.

Вам необходимо присоединиться к ним ЛЕВЫМ для тех случаев, когда они могут быть нулевыми, а затем сослаться на каждую из таблиц в вашем SELECT, чтобы показать атрибут relevent.

Я бы тоже не рекомендовал кросс-соединение. Вы должны выполнить соединение «ИЛИ» для таблицы персонала в предложении FROM, а не выполнять перекрестное соединение и фильтрацию в предложении WHERE.

РЕДАКТИРОВАТЬ: Извините, мой первый ответ был немного поспешным. Теперь был шанс посмотреть дальше. Из-за того, что дополнительный запросчик и атрибут дополнительного запросчика являются дубликатами, вам нужно разделить их оба на подзапрос. Кроме того, ваша дата изменения может отличаться для обоих значений. Так что я удвоил это. Это полностью не проверено и ни в коем случае не является «оптимальным» решением. Довольно сложно написать запрос без фактической базы данных для проверки. Надеюсь, это объяснит, что я имел в виду.

SELECT
    r.RequesterID,
    p.FirstName + ' ' + p.LastName AS RequesterName,
    sra1.ModifiedDate as UrgentModifiedDate,
    sra1.AttributeValue as Urgent,
    sra2.ModifiedDate as ClosedModifiedDate,
    sra2.AttributeValue as Closed
FROM
    Personnel AS p
INNER JOIN
    Requester AS r 
ON
(
    r.UserID = p.ContractorID
OR
    r.UserID = p.EmployeeID
)
LEFT OUTER JOIN
(
    SELECT
        sr1.RequesterID,
        sr1.ModifiedDate,
        sa1.Attribute,
        sa1.AttributeValue
    FROM
        SubRequester AS sr1
    INNER JOIN
        SubRequesterAttribute AS sa1
    ON
        sr1.SubRequesterID = sa1.SubRequesterID
    AND
        sa1.Attribute = 'Urgent'
) sra1
ON
    sra1.RequesterID = r.RequesterID
LEFT OUTER JOIN
(
    SELECT
        sr2.RequesterID,
        sr2.ModifiedDate,
        sa2.Attribute,
        sa2.AttributeValue
    FROM
        SubRequester AS sr2
    INNER JOIN
        SubRequesterAttribute AS sa2
    ON
        sr2.SubRequesterID = sa2.SubRequesterID
    AND
        sa2.Attribute = 'Closed'
) sra1
ON
    sra2.RequesterID = r.RequesterID

ВТОРОЕ РЕДАКТИРОВАНИЕ: Мое последнее редактирование состояло в том, что было несколько подзапросов, а также несколько атрибутов. Из вашего последнего комментария вы хотите показать все подзапросы и два атрибута приставки? Вы можете достичь этого следующим образом.

SELECT
    r.RequesterID,
    p.FirstName + ' ' + p.LastName AS RequesterName,
    sr.ModifiedDate,
    sa1.AttributeValue as Urgent,
    sa2.AttributeValue as Closed
FROM
    Personnel AS p
INNER JOIN
    Requester AS r 
ON
(
    r.UserID = p.ContractorID
OR
    r.UserID = p.EmployeeID
)
INNER JOI N
    SubRequester as sr
ON
    sr.RequesterID = r.RequesterID
LEFT OUTER JOIN
    SubRequesterAttribute AS sa1
ON
    sa1.SubRequesterID = sr.SubRequesterID
AND
    sa1.Attribute = 'Urgent'
LEFT OUTER JOIN
    SubRequesterAttribute AS sa2
ON
    sa2.SubRequesterID = sr.SubRequesterID
AND
    sa2.Attribute = 'Closed'
0 голосов
/ 23 марта 2009

Как правило, если у вас есть несколько строк и вы хотите объединить их в одну, GROUP BY является основным инструментом для достижения этой цели. Похоже, вы пытались пойти в этом направлении, но не совсем дошли. Вам нужно сгруппировать выражения, которые дублируются между строками, и применить групповые функции к другим выражениям, которые устранят значения NULL. Я использовал MIN в примере ниже, но вы могли бы также легко использовать MAX; Дело в том, что, поскольку не более одной строки будет иметь значение для этого выражения, это значение является как минимальным, так и максимальным.

SELECT
   r.RequesterID,
   sr.ModifiedDate,
   p.FirstName + ' ' + p.LastName AS RequesterName,
   MIN(
   CASE
     WHEN sa.Attribute = 'Urgent' THEN sa.AttributeValue
     ELSE NULL
   END
   ) AS Urgent,
   MIN(
   CASE
     WHEN sa.Attribute = 'Closed' THEN sa.AttributeValue 
     ELSE NULL
   END
   ) AS Closed
FROM
   Requester AS r 
   INNER JOIN SubRequester AS sr 
     ON r.RequesterID = sr.RequesterID
   INNER JOIN SubRequesterAttribute AS sa
     ON sr.SubRequesterID = sa.SubRequesterID
   CROSS JOIN Personnel AS p
WHERE 
     (r.UserID = p.ContractorID
     OR r.UserID = p.EmployeeID)
   AND 
     (sa.Attribute IN ('Urgent', 'Closed'))
GROUP BY r.RequesterID, sr.ModifiedDate, p.FirstName + ' ' + p.LastName
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...