2012-05-16 10 views
0

Я пытаюсь создать динамический Pivot, однако, похоже, он не работает.Pivot and filter

Таблица:

SELECT [CaseID], [ClientID] 
from [RegData] 

В настоящее время Возвращает:

CaseID--|ClientID| RecID 
------------------------ 
7845107 |115172 |410 
7845107 |164570 |1197 
7845107 |115655 |416 
7845107 |154244 |425 
7856846 |116684 |151 
7856846 |112354 |445 
7455444 |115172 |492 
7455444 |164570 |518 
7455444 |115655 |1297 
7455444 |154244 |681 

Мне нужно, чтобы вернуться, как:

CaseID--|Val1----|Val2----|Val3----|Val4----| 
7845107 |115172 |164570 |115655 |154244 | 
7856846 |116684 |112354 |  |  | 
7455444 |115172 |164570 |115655 |154244 | 

Тогда мне нужно найти случаи, когда CaseID разные, но VAL1, VAL2, VAL3 и т. д. одинаковы.

CaseID--|Val1----|Val2----|Val3----|Val4----| 
7845107 |115172 |164570 |115655 |154244 | 
7455444 |115172 |164570 |115655 |154244 | 
+0

Как вы полагаете, что 164570 является Val2 и 115655 является Val3? SQL Server необходимо каким-то образом поддерживать данные (или что-то детерминированное, что вы можете представить для запроса) для поддержки этого заказа. В запросе у вас нет ORDER BY, поэтому я подозреваю, что вы предполагаете, что, поскольку на этот раз данные были возвращены, это тот порядок, который всегда будет возвращен? Это распространенное заблуждение, но тем не менее это заблуждение. У вас есть еще одна колонка, которая может помочь диктовать ожидаемый заказ (например, столбец идентификации или даты/времени)? –

+0

Привет Аарон, очень справедливая точка. Чтобы свести к минимуму беспорядок, я опустил столбец «RecID», который на самом деле является уникальным идентификатором для каждой строки. – Rya

+0

Итак, эти строки упорядочены в вашем примере выше, указанном RecID? Обычно мы предпочитаем полную информацию ... Мы умные люди, и беспорядок обычно не замедляет нас. Поэтому я предлагаю вам добавить значения RecID, по крайней мере, к первому набору. –

ответ

1

Много об отказе от ответственности здесь. Опираясь на вас, вы заботитесь только о случаях, когда все 4 значения имеют значение. Я не тестировал, что произойдет, если в одном из случаев был 5-й клиент, который не соответствует, или если имеется более двух случаев с одним и тем же набором клиентов. Он работает для данных образца, которые вы предоставили, за исключением того, что значения, которые вы ожидаете увидеть в каждом столбце Value1/Value2 и т. Д., Представлены в другом порядке, чем ваш образец.

DECLARE @x TABLE(CaseID INT, ClientID INT); 

INSERT @x SELECT 7845107,115172 UNION ALL SELECT 7845107,164570 
UNION ALL SELECT 7845107,115655 UNION ALL SELECT 7845107,154244 
UNION ALL SELECT 7856846,116684 UNION ALL SELECT 7856846,112354 
UNION ALL SELECT 7455444,115172 UNION ALL SELECT 7455444,164570 
UNION ALL SELECT 7455444,115655 UNION ALL SELECT 7455444,154244; 

;WITH x AS 
(
    SELECT CaseID, ClientID, rn = ROW_NUMBER() OVER 
    (PARTITION BY CaseID ORDER BY ClientID) 
    FROM @x 
), 
y AS 
(
    SELECT x.CaseID, x.ClientID, x.rn 
    FROM x INNER JOIN x AS x2 
    ON x.CaseID <> x2.CaseID 
    AND x.ClientID = x2.ClientID 
    AND x.rn = x2.rn 
) 
SELECT CaseID, 
    Value1 = MAX(CASE WHEN rn = 1 THEN ClientID END), 
    Value2 = MAX(CASE WHEN rn = 2 THEN ClientID END), 
    Value3 = MAX(CASE WHEN rn = 3 THEN ClientID END), 
    Value4 = MAX(CASE WHEN rn = 4 THEN ClientID END) 
FROM y 
GROUP BY CaseID; 

Результаты:

CaseID Value1 Value2 Value3 Value4 
------- ------ ------ ------ ------ 
7455444 115172 115655 154244 164570 
7845107 115172 115655 154244 164570 
+0

Кажется не компилируется. Возникает проблема с после INSERT @x VALUES (7845107,115172), (7845107,164570), – Rya

+0

@Rya ВСТАВИТЬ каждую строку, затем выполнив INSERT INTO @x (val1, val2) и повторите INSERT INTO для каждого значения пара. Кажется, sql 2005 не может вставлять сразу несколько значений, если вы получите сообщение об ошибке. – YvesR

+0

Извините @ Rya, я пропустил тег SQL Server 2005 (этот синтаксис действителен для современных версий SQL Server). Конечно, вы могли бы также попробовать только запрос к своей таблице, а не против '@ x' - я включил только это, чтобы продемонстрировать, что он работает вроде как то, о чем вы просили. –

0

Это то, что я придумал. Не очень эффективно, но он работает ...

Я создал таблицу. Я знаю, что их было не более 9 случаев одного и того же в наборе, следовательно, Val9.

DECLARE 
    @totalRecords int, 
    @counter int, 
    @QueryCaseID int, 
    @QueryClientID int, 
    @queryVal1 int, 
    @queryVal2 int, 
    @queryVal3 int, 
    @queryVal4 int, 
    @queryVal5 int, 
    @queryVal6 int, 
    @queryVal7 int, 
    @queryVal8 int, 
    @queryVal9 int 

Set @totalRecords = (Select count(*) from RegData) +1 
Set @counter = 1 

-- Get the rows in the table and put them into the 'RegData_reformat' table 
While @counter < @totalRecords 
    Begin 

     -- get the CASEID to cross query to reformatted table 
     SET @QueryCaseID = (Select CaseID from RegData where RecID = @counter) 

     -- get the ClientId to cross query to reformatted table 
     SET @QueryClientID = (Select ClientID from RegData where RecID = @counter) 



     -- assign the columns to variables 
     SET @queryVal1 = (Select Val1 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal2 = (Select Val2 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal3 = (Select Val3 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal4 = (Select Val4 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal5 = (Select Val5 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal6 = (Select Val6 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal7 = (Select Val7 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal8 = (Select Val8 from RegData_reformat where CaseID = @QueryCaseID) 
     SET @queryVal9 = (Select Val9 from RegData_reformat where CaseID = @QueryCaseID) 


     --determine which column to insert the data into 


-- Insert the data into the formatted table 

     IF @queryVal1 IS NULL 
      BEGIN 
       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val1] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 2 test 
     else IF @queryVal2 IS NULL 
      BEGIN 
       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val2] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 3 test 
     else IF @queryVal3 IS NULL 
      BEGIN 
       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val3] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 4 test 
     else IF @queryVal4 IS NULL 
      BEGIN 
       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val4] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 5 test    
     else IF @queryVal5 IS NULL 
      BEGIN 

       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val5] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 6 test 
     else IF @queryVal6 IS NULL 
      BEGIN 

       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val6] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 7 test 
     else IF @queryVal7 IS NULL 
      BEGIN 

       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val7] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 8 test 
     else IF @queryVal8 IS NULL 
      BEGIN 

       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val8] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 

    -- Column 9 test 
     else IF @queryVal9 IS NULL 
      BEGIN 

       UPDATE [4DISCSReporting].[dbo].[RegData_reformat] 
       SET [Val9] = @QueryClientID 
       WHERE CaseID = @QueryCaseID 
      END 



     ELSE 
      BEGIN 
       print 'Ran out of columns to enter data into' 
       Select 'FATAL ERROR: ran out of columns to enter data into' as Error 
      END 



    set @counter = @counter +1 


    END