2016-06-22 23 views
18

Câu hỏi là khá nhiều trong tiêu đề. Tôi không thể tìm thấy bất kỳ tài liệu chi tiết nào liên quan đến sự khác biệt.Sự khác biệt giữa các toán tử khối lập phương, rollup và groupBy là gì?

Tôi nhận thấy sự khác biệt bởi vì khi hoán đổi cho nhau và các cuộc gọi hàm groupBy, tôi nhận được các kết quả khác nhau. Tôi nhận thấy rằng đối với kết quả bằng cách sử dụng 'khối lập phương', tôi nhận được rất nhiều giá trị null trên các biểu thức tôi thường nhóm lại.

Trả lời

38

Chúng không có ý định hoạt động theo cùng một cách. groupBy chỉ đơn giản là tương đương với mệnh đề GROUP BY trong SQL tiêu chuẩn. Nói cách khác

table.groupBy($"foo", $"bar") 

tương đương với:

SELECT foo, bar, [agg-expressions] FROM table GROUP BY foo, bar 

cube tương đương với CUBE phần mở rộng cho GROUP BY. Phải có danh sách các cột và áp dụng các biểu thức tổng hợp cho tất cả các kết hợp có thể có của các cột nhóm. Cho phép nói bạn có dữ liệu như thế này:

val df = Seq(("foo", 1L), ("foo", 2L), ("bar", 2L), ("bar", 2L)).toDF("x", "y") 
df.show 

// +---+---+ 
// | x| y| 
// +---+---+ 
// |foo| 1| 
// |foo| 2| 
// |bar| 2| 
// |bar| 2| 
// +---+---+ 

và bạn tính cube(x, y) với tính là một tập hợp:

df.cube($"x", $"y").count.show 

// +----+----+-----+  
// | x| y|count| 
// +----+----+-----+ 
// |null| 1| 1| <- count of records where y = 1 
// |null| 2| 3| <- count of records where y = 2 
// | foo|null| 2| <- count of records where x = foo 
// | bar| 2| 2| <- count of records where x = bar AND y = 2 
// | foo| 1| 1| <- count of records where x = foo AND y = 1 
// | foo| 2| 1| <- count of records where x = foo AND y = 2 
// |null|null| 4| <- total count of records 
// | bar|null| 2| <- count of records where x = bar 
// +----+----+-----+ 

Một chức năng tương tự như cuberollup đó tính tổng số phụ thứ bậc từ trái sang phải :

df.rollup($"x", $"y").count.show 
// +----+----+-----+ 
// | x| y|count| 
// +----+----+-----+ 
// | foo|null| 2| <- count where x is fixed to foo 
// | bar| 2| 2| <- count where x is fixed to bar and y is fixed to 2 
// | foo| 1| 1| ... 
// | foo| 2| 1| ... 
// |null|null| 4| <- count where no column is fixed 
// | bar|null| 2| <- count where x is fixed to bar 
// +----+----+-----+ 

Ju st để so sánh cho phép xem kết quả của đồng bằng groupBy:

df.groupBy($"x", $"y").count.show 

// +---+---+-----+ 
// | x| y|count| 
// +---+---+-----+ 
// |foo| 1| 1| <- this is identical to x = foo AND y = 1 in CUBE or ROLLUP 
// |foo| 2| 1| <- this is identical to x = foo AND y = 2 in CUBE or ROLLUP 
// |bar| 2| 2| <- this is identical to x = bar AND y = 2 in CUBE or ROLLUP 
// +---+---+-----+ 

Để tóm tắt:

  • Khi sử dụng đơn giản GROUP BY mỗi hàng được bao gồm chỉ một lần trong tóm tắt tương ứng của nó.
  • Với GROUP BY CUBE(..) mỗi hàng được bao gồm trong bản tóm tắt của từng kết hợp các cấp mà nó đại diện, bao gồm các ký tự đại diện. Một cách logic, sự trình bày ở trên là tương đương với một cái gì đó như thế này (giả sử chúng ta có thể sử dụng NULL placeholders):

    SELECT NULL, NULL, COUNT(*) FROM table 
    UNION ALL 
    SELECT x, NULL, COUNT(*) FROM table GROUP BY x 
    UNION ALL 
    SELECT NULL, y, COUNT(*) FROM table GROUP BY y 
    UNION ALL 
    SELECT x, y, COUNT(*) FROM table GROUP BY x, y 
    
  • Với GROUP BY ROLLUP(...) cũng tương tự như CUBE nhưng việc phân cấp bằng cách điền colums từ trái sang phải.

    SELECT NULL, NULL, COUNT(*) FROM table 
    UNION ALL 
    SELECT x, NULL, COUNT(*) FROM table GROUP BY x 
    UNION ALL 
    SELECT x, y, COUNT(*) FROM table GROUP BY x, y 
    

ROLLUPCUBE đến từ phần mở rộng kho dữ liệu vì vậy nếu bạn muốn có được một sự hiểu biết rõ hơn về cách làm việc này bạn cũng có thể kiểm tra tài liệu của RDMBS yêu thích của bạn. Ví dụ: PostgreSQL giới thiệu cả trong 9.5 và these are relatively well documented.

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