2010-08-12 25 views
7

tôi có một tập hợp năng động của dữ liệu X dạng:Hiệu ứng nhóm không?

---------------------------------- 
x.id | x.allocated | x.unallocated 
---------------------------------- 
foo | 2   | 0 
bar | 1   | 2 
---------------------------------- 

Và tôi cần để có được một kết quả của Y (thứ tự là không quan trọng):

---------------------------------- 
y.id | y.state 
---------------------------------- 
foo | allocated 
foo | allocated 
bar | allocated 
bar | unallocated 
bar | unallocated 
---------------------------------- 

Tôi có một giải pháp dựa trên UTF, nhưng tôi đang tìm kiếm siêu hiệu quả vì vậy tôi đang tự hỏi nếu có một tuyên bố dựa trên, cách phi thủ tục để có được loại "ungroup bởi" có hiệu lực?

Nó giống như một trục xoay, nhưng bộ não của tôi không thể đến đó ngay bây giờ.

+1

Phiên bản SQL Server nào? – AakashM

+0

2K5 fwiw (omg padding) – annakata

Trả lời

6

sử dụng SQL Server 2005, UNPIVOT, và CTE bạn có thể thử một cái gì đó giống như

DECLARE @Table TABLE(
     id VARCHAR(20), 
     allocated INT, 
     unallocated INT 
) 

INSERT INTO @Table SELECT 'foo', 2, 0 
INSERT INTO @Table SELECT 'bar', 1, 2 

;WITH vals AS (
     SELECT * 
     FROM  
     (
      SELECT id, 
        allocated, 
        unallocated 
      FROM @Table 
     ) p 
     UNPIVOT (Cnt FOR Action IN (allocated, unallocated)) unpvt 
     WHERE Cnt > 0 
) 
, Recurs AS (
     SELECT id, 
       Action, 
       Cnt - 1 Cnt 
     FROM vals 
     UNION ALL 
     SELECT id, 
       Action, 
       Cnt - 1 Cnt 
     FROM Recurs 
     WHERE Cnt > 0 

) 
SELECT id, 
     Action 
FROM Recurs 
ORDER BY id, action 
+0

Tôi biết nó không thể thay đổi được :) Cảm ơn. – annakata

7

Nếu bạn có bảng số trong cơ sở dữ liệu của mình, bạn có thể sử dụng bảng đó để giúp nhận kết quả của mình. Trong cơ sở dữ liệu của tôi, tôi có một bảng có tên là Numbers với cột Num.

Declare @Temp Table(id VarChar(10), Allocated Int, UnAllocated Int) 

Insert Into @Temp Values('foo', 2, 0) 
Insert Into @Temp Values('bar',1, 2) 

Select T.id,'Allocated' 
From @Temp T 
     Inner Join Numbers 
      On T.Allocated >= Numbers.Num 
Union All 
Select T.id,'Unallocated' 
From @Temp T 
     Inner Join Numbers 
      On T.unAllocated >= Numbers.Num 
+0

Đơn giản, thanh lịch, nhưng rõ ràng là phân tích ở phạm vi số cực trừ khi bạn muốn tạo các hàng bigint.max trong bảng của mình. Gần như chắc chắn là giải pháp hiệu quả nhất, nhưng tôi không thích làm ô nhiễm DB của tôi với các cơ chế hỗ trợ. – annakata

+0

Làm ô nhiễm DB với cơ chế hỗ trợ? Có thật không? Tôi nghĩ đó là định nghĩa của chỉ mục. Các chỉ mục tồn tại để hỗ trợ hiệu suất truy vấn DB của bạn. Tôi đặt cược bạn có một bó của những người trong cơ sở dữ liệu của bạn. –

+0

@annakata - Bạn là một người nghiện rượu thật! Bạn có nhận ra rằng các con số trong câu hỏi của OP đang thực sự được dịch sang hàng thực trong một tập kết quả thực? Bất kể rowcount sẽ là của tập kết quả cuối cùng, nếu máy chủ và ứng dụng có thể xử lý điều đó, họ có thể xử lý một bảng số để đi cùng với nó. Cho phép một số hệ thống khổng lồ không khả thi, một bảng có giá trị số nguyên 2^31-1 trong nó chỉ khoảng 8 Gb dữ liệu. Vì vậy, trả lại 2.147.483.647 hàng là không có vấn đề gì và tôi đảm bảo giải pháp này sẽ làm tốt hơn CTE của bạn theo thứ tự độ lớn. – ErikE

0

Câu trả lời này chỉ là để ping trở lại G Mastros và không cần bất kỳ upvotes. Tôi nghĩ anh ấy sẽ đánh giá cao hiệu suất tăng lên cho truy vấn cao cấp của mình.

SELECT 
    T.id, 
    CASE X.Which WHEN 1 THEN 'Allocated' ELSE 'Unallocated' END 
FROM 
    @Temp T 
    INNER JOIN Numbers N 
     On N.Num <= CASE X.Which WHEN 1 THEN T.Allocated ELSE T.Unallocated END 
    CROSS JOIN (SELECT 1 UNION ALL SELECT 2) X (Which) 
+0

Có phải 'Số' là bảng/khung hệ thống không? Nó có sẵn trong 'SQL Server 2005' không? –

+1

Nó chỉ là một bảng với các con số 1 đến 100.000 hoặc một số tiền cao. – ErikE

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