2012-05-16 235 views
0

我想创建一个动态的枢轴,但似乎无法让它工作。枢轴和过滤器

表:

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