2017-09-07 18 views
5

Tôi có một bảng trông như thế nàytrục hàng đến 14 cột như 7 tuples

assignmentID personID projectCode projectCodePercent 
-------------- ------------ ----------- ----------- 
642    13527  511   75.00 
642    13527  621   25.00 
650    12000  555   50.00 
650    12000  520   25.00 
650    12000  621   25.00 
240    56000  721   100.00 

Tôi muốn biết sự phân bố của (porjectCode, projectCodePercent) như tuple cho mỗi bài tập. Bài tập có thể có tối đa 7 bộ. nếu họ không có 7 thì trường đó chỉ có thể để trống. Vì vậy, đầu ra mong muốn sẽ trông bên dưới:

assignmentID projectCode1 projectCodePercent1 projectCode2 projectCodePercent2 projectCode3 projectCodePercent3 projectCode4 projectCodePercent4 projectCode5 projectCodePercent5 projectCode6 projectCodePercent6 projectCode7 projectCodePercent7 
------------ ------------ ------------------- ------------ ------------------- ------------- ------------------- ------------- ------------------- ------------- ------------------- ------------- ------------------- ------------ ---------------- 
642   511   75.00     621   25.00 
650   555   50.00     520   25.00     621    25.00 
240   721   100.00 

EDIT: thứ tự bản ghi không quan trọng. I E. mà kỷ lục được gán cho projectCode1 hoặc projectCode2 .... và vân vân không quan trọng miễn là quyền projectCode phù hợp với projectCodePercent đúng

+0

gì định nghĩa các đơn đặt hàng kỷ lục? Tại sao 520 projectcode2 thay vì 555 hoặc 621? Ngẫu nhiên? không quan trọng? – xQbert

+0

@xQbert Cảm ơn bạn đã làm rõ. thứ tự kỷ lục không quan trọng. –

Trả lời

3

Vì bạn không cần phải đi động. Một cách tiếp cận là UNPivot dữ liệu thông qua một ứng dụng CROSS.

Ví dụ

Select * 
From (
     Select assignmentID  
       ,B.* 
      From (
        Select *,Grp = Row_Number() over (Partition By assignmentID order by projectCode) 
        From YourTable 
       ) A 
      Cross Apply (values ('projectCode'  +left(A.Grp,1),cast(projectCode as varchar(max))) 
           ,('projectCodePercent'+left(A.Grp,1),cast(projectCodePercent as varchar(max))) 
           ,('projectCode'  +left(A.Grp,1),cast(projectCode as varchar(max))) 
         ) B(Item,Value) 
    ) A 
Pivot (max([Value]) For [Item] in (projectCode1,projectCodePercent1,projectCode2,projectCodePercent2,projectCode3,projectCodePercent3,projectCode4,projectCodePercent4,projectCode5,projectCodePercent5,projectCode6,projectCodePercent6,projectCode7,projectCodePercent7)) p 

Returns

enter image description here

+1

Vì vậy, sạch hơn nhiều (từ quan điểm thực thi) so với những gì tôi đã làm. Tôi thực sự cần phải chơi xung quanh với chéo áp dụng nhiều hơn nữa. Mặc dù tôi không ghen tị với người mới, những người phải duy trì ở trên ban đầu: P – xQbert

+1

@ xQbert Vì đó là một số cố định, suy nghĩ đầu tiên của tôi là cách tiếp cận của bạn. Chỉ cần đặt một thay thế. –

+2

Một điều tốt ở đây: P Nên luôn tận dụng các tính năng mới khi có thể. Họ cung cấp những lợi ích đáng kể thường. – xQbert

4

DEMO: http://rextester.com/IYDJ29385

  1. CTE mang lại cho tôi dữ liệu mẫu để chơi với
  2. CTE2 chỉ cần gán số hàng cho mỗi phép gánId và PersonId (bạn chỉ có thể sử dụng chế độ xem nội tuyến)
  3. Sau đó, chúng tôi sử dụng tuyên bố trường hợp để xoay vòng dữ liệu dựa trên số hàng được tạo. Sự sụp đổ của phương pháp này là tất cả 14 cột luôn được trả về. Sử dụng SQL động, bạn chỉ có thể hiển thị các cột đó khi cần.

Điều này giả định rằng mã định danhDi và personId và mã dự án là duy nhất. Nếu nhiều mã dự án có thể tồn tại cho cùng một nhiệm vụ và người đó thì chúng tôi sẽ cần phải làm điều gì đó khác thay vì tối đa.

WITH CTE (assignmentID, personID, projectCode, projectCodePercent) as (
SELECT 642,    13527,  511,   75.00 UNION ALL 
SELECT 642,    13527,  621,   25.00 UNION ALL 
SELECT 650,    12000,  555,   50.00 UNION ALL 
SELECT 650,    12000,  520,   25.00 UNION ALL 
SELECT 650,    12000,  621,   25.00 UNION ALL 
SELECT 240,    56000,  721,   100.00), 
cte2 as (SELECT A.*, row_number() over (partition by AssignmentID, PersonID order by projectCode) RN 
     FROM cte A) 
SELECT AssignmentID 
    , PersonID 
    , max(CASE WHEN RN = 1 then projectCode end) as projectCode1 
    , max(CASE WHEN RN = 1 then ProjectcodePercent end) as ProjectcodePercent1 
    , max(CASE WHEN RN = 2 then projectCode end) as projectCode2 
    , max(CASE WHEN RN = 2 then ProjectcodePercent end) as ProjectcodePercent2 
    , max(CASE WHEN RN = 3 then projectCode end) as projectCode3 
    , max(CASE WHEN RN = 3 then ProjectcodePercent end) as ProjectcodePercent3 
    , max(CASE WHEN RN = 4 then projectCode end) as projectCode4 
    , max(CASE WHEN RN = 4 then ProjectcodePercent end) as ProjectcodePercent4 
    , max(CASE WHEN RN = 5 then projectCode end) as projectCode5 
    , max(CASE WHEN RN = 5 then ProjectcodePercent end) as ProjectcodePercent5 
    , max(CASE WHEN RN = 6 then projectCode end) as projectCode6 
    , max(CASE WHEN RN = 6 then ProjectcodePercent end) as ProjectcodePercent6 
    , max(CASE WHEN RN = 7 then projectCode end) as projectCode7 
    , max(CASE WHEN RN = 7 then ProjectcodePercent end) as ProjectcodePercent7 
FROM CTE2 
Group by AssignmentID, personId 

Cho chúng tôi:

+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
| | AssignmentID | PersonID | projectCode1 | ProjectcodePercent1 | projectCode2 | ProjectcodePercent2 | projectCode3 | ProjectcodePercent3 | projectCode4 | ProjectcodePercent4 | projectCode5 | ProjectcodePercent5 | projectCode6 | ProjectcodePercent6 | projectCode7 | ProjectcodePercent7 | 
+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
| 1 |   650 | 12000 |   520 |    25,00 | 555   | 50,00    | 621   | 25,00    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
| 2 |   642 | 13527 |   511 |    75,00 | 621   | 25,00    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
| 3 |   240 | 56000 |   721 |    100,00 | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | NULL   | NULL    | 
+----+--------------+----------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+--------------+---------------------+ 
+0

Tùy chọn tốt hơn từ quan điểm kế hoạch thực hiện – JamieD77

+0

+ 1 Cảm ơn. Tôi thích điều này vì nó rất dễ hiểu. Tôi dự định sử dụng điều này làm truy vấn phụ của mình. truy vấn hiện tại của tôi đã rất lớn và phức tạp nên tôi có thể sử dụng câu trả lời của John bên dưới. –

+0

SQL phức tạp là 1 lý do CTE được tạo IMO: P – xQbert

Các vấn đề liên quan