2012-06-18 38 views
5

Tôi có một bảng chứa một loạt tên, sự kiện và ngày tháng. Tôi đã tạo một trường mới 'evt5_date' có liên quan đến một sự kiện cụ thể (evt5).Làm cách nào để tạo tham gia bằng cách sử dụng 'lớn hơn' và 'nhóm theo'?

Mỗi tên có thể có một số sự kiện, thời gian của từng sự kiện được ghi lại trong trường evt_date. Hai sự kiện evt1evt2 có liên quan đến evt5.

Tôi muốn chèn ngày xuất hiện đầu tiên của một evt5 vào tất cả evt1evt2 hàng trước evt5. Nếu không có evt5 sau evt1 hoặc evt2 thì trường này sẽ để trống.

Tất cả điều này phải được thực hiện cho mỗi name. Có vài nghìn tên khác nhau. Tôi đã chỉ hiển thị 2 trong các dữ liệu dưới đây

bảng dữ liệu hiện tại - không có giá trị trong evt5_date

name  evt_date  event evt5_date 
name-1 2010-06-30  evt1  
name-1 2009-10-30  evt5 
name-1 2009-09-30  evt2  
name-1 2009-06-30  evt5   
name-1 2009-03-30  evt5  
name-1 2009-02-28  evt2  
name-1 2009-01-30  evt1  
name-2 2005-05-30  evt2 
name-2 2005-03-30  evt5 
name-2 2005-01-30  evt1  

Làm thế nào tôi muốn nó trông - giá trị trong lĩnh vực evt5_date

name  evt_date  event evt5_date 
name-1 2010-06-30  evt1  
name-1 2009-10-30  evt5 
name-1 2009-09-30  evt2  2009-10-30 
name-1 2009-06-30  evt5   
name-1 2009-03-30  evt5  
name-1 2009-02-28  evt2  2009-03-30 
name-1 2009-01-30  evt1  2009-03-30 
name-2 2005-05-30  evt2 
name-2 2005-03-30  evt5 
name-2 2005-01-30  evt1  2005-03-31 

Tôi đã cố gắng thực hiện cập nhật bằng mã bên dưới, nhưng tôi không biết cách chỉ định liên kết giữa ngày evt5 lớn hơn evt_date của evt1 và evt2 trong khi cũng nhóm g bởi evt5 để thu được evt_date liên quan đến evt5 gần đây nhất.

Tôi cũng cần nhóm theo tên vì các sự kiện dành riêng cho từng tên.

update mytable as t1 
set t1.evt5_date = (select min(t2.evt_date) from mytable as t2 
        where t2.event = 'evt5' AND 
          t2.evt_date > t1.evt_date 
        group by name) 
where 
    t1.event in ('evt1', 'evt2') 

Mọi đề xuất sẽ được đánh giá cao. Cảm ơn

Cập nhật giải pháp cuối cùng - một số thay đổi nhỏ để trả lời được cung cấp bởi @biziclop để duy trì tính toàn vẹn của name

UPDATE mytable AS t1 
INNER JOIN 
    (
     SELECT 
      a.name, a.evt_date, 
     MIN(b.evt_date) AS nearest_date 
     FROM  mytable AS a 
     INNER JOIN mytable AS b ON b.event = 'evt5' 
          AND b.evt_date > a.evt_date 
          AND a.name = b.name  -- needed this additional condition 
     GROUP BY a.name, a.evt_date      -- added 'a.name' to 'group by' 
    ) AS nearest_dates 
     ON nearest_dates.evt_date = t1.evt_date AND 
     nearest_dates.name = t1.name     -- added this additional condition 
SET t1.evt5_date = nearest_dates.nearest_date 
WHERE t1.event IN ('evt1', 'evt2'); 
+0

người ??? a2.evt5_date, tôi không nhận được nó, bạn phải cập nhật T1 và thiết lập a2 ? – jcho360

+0

@ jcho360 - xin lỗi đó là lỗi đánh máy, nó được cho là 't1'. Đã sửa lỗi. –

+0

bạn có thể đặt một số cấu trúc và dữ liệu trong sqlfiddle và chia sẻ nó? – jcho360

Trả lời

4

Tôi cố định báo cáo cập nhật của bạn, tôi nghĩ rằng nó hoạt động ngay bây giờ. Tôi đã bỏ qua phần GROUP BY name vì nó không có ý nghĩa trong phiên bản của bạn.

UPDATE mytable AS t1 
INNER JOIN 
    (
     SELECT 
     a.evt_date, 
     MIN(b.evt_date) AS nearest_date 
     FROM  mytable AS a 
     INNER JOIN mytable AS b ON b.event = 'evt5' 
          AND b.evt_date > a.evt_date 
     GROUP BY a.evt_date 
    ) AS nearest_dates ON nearest_dates.evt_date = t1.evt_date 
SET t1.evt5_date = nearest_dates.nearest_date 
WHERE t1.event IN ('evt1', 'evt2'); 

Đầu tiên một số xác minh: http://sqlfiddle.com/#!2/309ac/6

Các thức UPDATE truy vấn: http://sqlfiddle.com/#!2/80c3c/1

+0

cảm ơn rất nhiều về điều này và cho lời giải thích tuyệt vời về sqlfiddle. Tôi đã thực hiện một số thay đổi nhỏ đối với các tên khác nhau (như được hiển thị trong câu hỏi được cập nhật). Tôi thực sự đánh giá cao sự giúp đỡ. –

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