2012-10-16 35 views
5

Tôi có cấu trúc sau:SQL: tổng của một giá trị nhưng chỉ cho các id riêng biệt - tổng điều kiện?

Ngày có nhiều sự kiện typ1 và typ2, trong đó typ1 và typ2 có khóa ngoài vào ngày tương ứng. Typ2 cũng có thời gian.

Bây giờ tôi muốn đếm tất cả các sự kiện typ1, tất cả các sự kiện typ2 và tổng thời lượng typ2.

Ví dụ dữ liệu:

ngày:

ID = 1 | Date = yesterday | ... 

Typ1:

ID = 1 | FK_DAY = 1 | ... 

ID = 2 | FK_DAY = 1 | ... 

Typ2:

ID = 1 | FK_DAY = 1 | duration = 10 

ID = 2 | FK_DAY = 1 | duration = 20 

bây giờ tôi muốn kết quả:

Day.ID = 1 | countTyp1 = 2 | countTyp2 = 2 | sumDurationTyp2 = 30 

Vấn đề của tôi là tổng, tôi cần một cái gì đó như "tổng hợp cho typ2.ID riêng biệt" ... Có ai biết một cách để giải quyết điều đó?

Tôi đang sử dụng một cái gì đó như sau, nhưng điều đó tất nhiên không làm việc theo cách tôi muốn:

SELECT day.id, 
    count(DISTINCT typ1.id), 
    count(DISTINCT typ2.id), 
    sum(duration) AS duration 
FROM days 
    LEFT JOIN typ 
      ON day.id = typ1.id 
    LEFT JOIN typ2 
      ON day.id = typ2.id 
GROUP BY day.id; 
+0

RDBMS và phiên bản nào? – Tobsey

Trả lời

13

cách tiếp cận chung của tôi đến đây là để được tổng hợp trước mỗi bảng, trước khi gia nhập .

Một phần vì bạn không thực sự tổng hợp các giá trị riêng biệt (nếu mỗi hàng trong số hai hàng có 10, câu trả lời vẫn là 20).

Nhưng chủ yếu là vì nó thực sự đơn giản theo cách đó. Các truy vấn con thực hiện tổng hợp, sau đó các phép nối là tất cả 1: 1.

SELECT 
    days.id, 
    typ_agg.rows, 
    type2_agg.rows, 
    type2_agg.duration 
FROM 
    days 
LEFT JOIN 
    (SELECT fk_day, COUNT(*) as rows FROM typ GROUP BY fk_day) AS typ_agg 
    ON days.id = typ_agg.fk_day 
LEFT JOIN 
    (SELECT fk_day, COUNT(*) as rows, SUM(duration) as duration FROM typ2 GROUP BY fk_day) AS typ2_agg 
    ON days.id = typ2_agg.fk_day 
+1

. . Tôi hy vọng đây là câu trả lời được chấp nhận, bởi vì đó là cách tiếp cận đúng. –

+0

Cảm ơn rất nhiều, trong truy vấn thực tế của tôi phức tạp hơn, điều đó thực sự làm cho nó dễ đọc hơn nhiều – prom85

0
SELECT day.id, 
    count(DISTINCT typ1.id), 
    count(DISTINCT typ2.id), 
    (select sum(t2.duration) 
    from typ2 t2 
    where t2.id = day.id 
    ) AS duration 
FROM days 
    LEFT JOIN typ 
      ON day.id = typ1.id 
    LEFT JOIN typ2 
      ON day.id = typ2.id 
GROUP BY day.id; 
+0

Điều này giới thiệu các truy vấn phụ bổ sung và tôi tin rằng OP đang tìm kiếm một giải pháp truy vấn đơn lẻ. Câu trả lời của bạn có nghĩa là hàm ý nó không thể được viết dưới dạng một truy vấn đơn lẻ? – Yuck

+0

@Yuck - Nó nói 'truy vấn đơn' hoặc 'không có truy vấn phụ' ở đâu. Tại sao bạn xem xét 'truy vấn phụ' không phải là một phần của một 'truy vấn đơn'? * (Nếu chúng là một 'phụ' của một cái gì đó, chúng là một phần của nó, và 'nó' là một truy vấn đơn ...) * Chưa kể rằng một số RDBMS là ngoại lệ khi mở rộng các truy vấn phụ. – MatBailie

+0

FWIW không phải là sự đánh giá của tôi. Và ít nhất trong SQL Server, kiểu truy vấn này có (thường) các hình phạt hiệu suất nghiêm trọng. Không phải là nó sai. Tôi chỉ hỏi câu hỏi - liệu có cách nào để làm điều này mà không cần chọn lựa các bảng liên quan? – Yuck

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