SQL получает несколько столбцов в один столбец - PullRequest
2 голосов
/ 08 декабря 2011

У меня есть этот запрос, который я использую для создания отчета:

SELECT DISTINCT 
    Appointment.ActivityId, Appointment.ScheduledStart, Appointment.OwnerIdName, Contact.AccountIdName, Appointment.new_ContactPersonName, 
        Appointment.Subject, Appointment.new_ColderNotes, Account.AccountId, Contact_1.ContactId, SystemUser.SystemUserId, SystemUser.FullName AS OptionalOwner, 
        Contact_1.FullName AS OptionalContact, Account.Name AS OptionalAccount, ActivityParty.PartyId, ActivityParty.ParticipationTypeMask, 
        Contact_1.FullName AS RequiredContact, Account.Name AS RequiredAccount, SystemUser.FullName AS RequiredOwner, Account.new_BusinessUnit
FROM
    Contact AS Contact_1 RIGHT OUTER JOIN
        Account RIGHT OUTER JOIN
        SystemUser RIGHT OUTER JOIN
        Appointment INNER JOIN
        ActivityParty ON Appointment.ActivityId = ActivityParty.ActivityId ON SystemUser.SystemUserId = ActivityParty.PartyId ON Account.AccountId = ActivityParty.PartyId ON
        Contact_1.ContactId = ActivityParty.PartyId LEFT OUTER JOIN
        Contact ON Appointment.new_ContactPerson = Contact.ContactId

Возвращает строки для каждого типа пользователя. Итак, одна строка для Required пользователя и одна строка для Optional User и т. Д.

Это небольшая выборка данных:

ActivityId  ScheduledStart  OwnerIdName AccountIdName   new_ContactPersonName   Subject new_ColderNotes AccountId   ContactId   SystemUserId    OptionalOwner   OptionalContact OptionalAccount PartyId ParticipationTypeMask   RequiredContact RequiredAccount RequiredOwner   new_BusinessUnit
    f9ca2637-580a-e111-b263-001ec928e97f    11/17/2011 3:00:00 PM   Bob Schulze Surmodics Pharmaceuticals   Jason Kennedy   Sales Visit - Surmodics NULL    NULL    NULL    f69530fc-da00-e111-b263-001ec928e97f    Bob Schulze NULL    NULL    f69530fc-da00-e111-b263-001ec928e97f    7   NULL    NULL    Bob Schulze NULL
    f9ca2637-580a-e111-b263-001ec928e97f    11/17/2011 3:00:00 PM   Bob Schulze Surmodics Pharmaceuticals   Jason Kennedy   Sales Visit - Surmodics NULL    NULL    NULL    f69530fc-da00-e111-b263-001ec928e97f    Bob Schulze NULL    NULL    f69530fc-da00-e111-b263-001ec928e97f    9   NULL    NULL    Bob Schulze NULL
    f9ca2637-580a-e111-b263-001ec928e97f    11/17/2011 3:00:00 PM   Bob Schulze Surmodics Pharmaceuticals   Jason Kennedy   Sales Visit - Surmodics NULL    c629fb14-1101-e111-b263-001ec928e97f    NULL    NULL    NULL    NULL    Surmodics Pharmaceuticals   c629fb14-1101-e111-b263-001ec928e97f    5   NULL    Surmodics Pharmaceuticals   NULL    NULL
    f9ca2637-580a-e111-b263-001ec928e97f    11/17/2011 3:00:00 PM   Bob Schulze Surmodics Pharmaceuticals   Jason Kennedy   Sales Visit - Surmodics NULL    c629fb14-1101-e111-b263-001ec928e97f    NULL    NULL    NULL    NULL    Surmodics Pharmaceuticals   c629fb14-1101-e111-b263-001ec928e97f    8   NULL    Surmodics Pharmaceuticals   NULL    NULL

Как видите, они одинаковы ActivityID, но имеют разные ParticipationTypeMasks это 5, 7, 9.

Используя все это при создании отчета, я получаю что-то вроде этого:

enter image description here

Создает строку для каждого ParticipationMask. Я пытаюсь сделать так, чтобы ParticipationMask равнялось 1, 2 или 3, эти имена попадали в столбец «Продажи», а если 4, 5, 6 - в столбец «Другие», и в каждой активность, а не один за ParticipationMask. В любом случае, чтобы сделать это? Я застрял. Я готов сделать это в SQL или SSRS.

Спасибо!

Ответы [ 3 ]

1 голос
/ 08 декабря 2011

Это выстрел в темноте, потому что мы на самом деле не знаем ваших данных, но если вам нравится существующий запрос, возможно, можно будет просто использовать его дважды, но с предложением where, например:

SELECT
-- Common stuff?
ISNULL(Sales.ActivityId, Other.ActivityId), ISNULL(Sales.ScheduledStart, Other.ScheduledStart), ISNULL(Sales.OwnerIdName, Other.OwnerIdName), ISNULL(Sales.AccountIdName, Other.AccountIdName), ISNULL(Sales.new_ContactPersonName, Other.new_ContactPersonName), ISNULL(Sales.[Subject], Other.[Subject]), ISNULL(Sales.new_ColderNotes, Other.new_ColderNotes)
-- Sales stuff?
, Sales.AccountId, Sales.ContactId, Sales.SystemUserId, Sales.OptionalOwner, Sales.OptionalContact, Sales.OptionalAccount, Sales.PartyId, Sales.ParticipationTypeMask, Sales.RequiredContact, Sales.RequiredAccount, Sales.RequiredOwner, Sales.new_BusinessUnit
-- Other Stuff?
, Other.AccountId, Other.ContactId, Other.SystemUserId, Other.OptionalOwner, Other.OptionalContact, Other.OptionalAccount, Other.PartyId, Other.ParticipationTypeMask, Other.RequiredContact, Other.RequiredAccount, Other.RequiredOwner, Other.new_BusinessUnit
FROM
(
    SELECT DISTINCT 
        Appointment.ActivityId, Appointment.ScheduledStart, Appointment.OwnerIdName, Contact.AccountIdName, Appointment.new_ContactPersonName, 
            Appointment.Subject, Appointment.new_ColderNotes, Account.AccountId, Contact_1.ContactId, SystemUser.SystemUserId, SystemUser.FullName AS OptionalOwner, 
            Contact_1.FullName AS OptionalContact, Account.Name AS OptionalAccount, ActivityParty.PartyId, ActivityParty.ParticipationTypeMask, 
            Contact_1.FullName AS RequiredContact, Account.Name AS RequiredAccount, SystemUser.FullName AS RequiredOwner, Account.new_BusinessUnit
    FROM
        Contact AS Contact_1 RIGHT OUTER JOIN
            Account RIGHT OUTER JOIN
            SystemUser RIGHT OUTER JOIN
            Appointment INNER JOIN
            ActivityParty ON Appointment.ActivityId = ActivityParty.ActivityId ON SystemUser.SystemUserId = ActivityParty.PartyId ON Account.AccountId = ActivityParty.PartyId ON
            Contact_1.ContactId = ActivityParty.PartyId LEFT OUTER JOIN
            Contact ON Appointment.new_ContactPerson = Contact.ContactId
    -- Limit this part to Sales?
    WHERE ParticipationTypeMask BETWEEN 1 AND 3
) as Sales
FULL OUTER JOIN
(
    SELECT DISTINCT 
        Appointment.ActivityId, Appointment.ScheduledStart, Appointment.OwnerIdName, Contact.AccountIdName, Appointment.new_ContactPersonName, 
            Appointment.Subject, Appointment.new_ColderNotes, Account.AccountId, Contact_1.ContactId, SystemUser.SystemUserId, SystemUser.FullName AS OptionalOwner, 
            Contact_1.FullName AS OptionalContact, Account.Name AS OptionalAccount, ActivityParty.PartyId, ActivityParty.ParticipationTypeMask, 
            Contact_1.FullName AS RequiredContact, Account.Name AS RequiredAccount, SystemUser.FullName AS RequiredOwner, Account.new_BusinessUnit
    FROM
        Contact AS Contact_1 RIGHT OUTER JOIN
            Account RIGHT OUTER JOIN
            SystemUser RIGHT OUTER JOIN
            Appointment INNER JOIN
            ActivityParty ON Appointment.ActivityId = ActivityParty.ActivityId ON SystemUser.SystemUserId = ActivityParty.PartyId ON Account.AccountId = ActivityParty.PartyId ON
            Contact_1.ContactId = ActivityParty.PartyId LEFT OUTER JOIN
            Contact ON Appointment.new_ContactPerson = Contact.ContactId
    -- Limit this part to Other?
    WHERE ParticipationTypeMask BETWEEN 4 AND 6
) AS Other ON Sales.ActivityId = Other.ActivityId -- More cols for join?
0 голосов
/ 08 декабря 2011

Один из способов - дважды присоединиться к вашему столу и добавить фильтры ParticipationMask в предложение Join.Например,

  JOIN activityparty activityparty_sales
    ON appointment.activityid = activityparty_sales.activityid 
    AND activityparty_sales.participationtypemask IN ( 1, 2, 3 ) 

И

   JOIN activityparty activityparty_other 
     ON appointment.activityid = activityparty_other.activityid 
     AND activityparty_other.participationtypemask IN ( 4, 5, 6 )

Это несколько сложно (по крайней мере для меня), потому что у вас есть куча Right joins с вложенными объединениями.

Я преобразовал их в более стандартные объединения (но без возможности тестирования, я могу ошибаться)

SELECT [your fields] 
FROM   appointment 
       INNER JOIN activityparty activityparty_sales 
         ON appointment.activityid = activityparty_sales.activityid 
            AND activityparty_sales.participationtypemask IN ( 1, 2, 3 ) 
       LEFT JOIN systemuser systemuser_sales 
         ON systemuser_sales.systemuserid = activityparty_sales.partyid 
       LEFT JOIN ACCOUNT account_sales 
         ON account_sales.accountid = activityparty_sales.partyid 
       LEFT JOIN contact AS contact_1_sales 
         ON contact_1_sales.contactid = activityparty_sales.partyid 
       LEFT OUTER JOIN contact contact_sales 
         ON appointment.new_contactperson = contact_sales.contactid 

       INNER JOIN activityparty activityparty_other 
         ON appointment.activityid = activityparty_other.activityid 
            AND activityparty_other.participationtypemask IN ( 4, 5, 6 ) 
       LEFT JOIN systemuser systemuser_other 
         ON systemuser_other.systemuserid = activityparty_other.partyid 
       LEFT JOIN ACCOUNT account_other 
         ON account_other.accountid = activityparty_other.partyid 
       LEFT JOIN contact AS contact_1_other 
         ON contact_1_other.contactid = activityparty_other.partyid 
       LEFT OUTER JOIN contact contact_other 
         ON appointment.new_contactperson = contact_other.contactid 

Еще одна вещь, которая усложняет это, заключается в том, что без знания ваших данных может быть несколькоSales и Other

Если это так, то вам нужно добавить два CTE, которые используют Row_Number, а затем добавить предложение where

WHERE 
 (CTE_sales.activityid  is null 
   or CTE_other.activityid  is null 
    or CTE_sales.RN = CTE_other.RN)

* На самом деле CTE не является 'плохая идея

0 голосов
/ 08 декабря 2011

Если я правильно интерпретирую ваш вопрос, похоже, вам нужно использовать подзапросы.

Напишите один подзапрос, чтобы найти данные «Продажи» для действия, а другой, чтобы найти ваши «Прочие» данные для действия.Затем вы можете присоединить каждого обратно к базовой записи активности.Обратите внимание, что в зависимости от того, как именно ваши данные структурированы, подзапросы могут быть такими же простыми, как добавление предложения AND к объединению, которое отфильтровывает его до нужных типов записей, а затем повторение объединения по различным критериям.

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

...