2009-05-08 10 views
19

Tôi có một câu hỏi chung mà tôi sẽ cố gắng giải thích bằng cách sử dụng một ví dụ.MySQL/SQL: Cập nhật với truy vấn con tương ứng từ bảng được cập nhật chính nó

Nói rằng tôi có một bảng với các lĩnh vực: "id", "tên", "thể loại", "diện mạo" và "tỷ lệ"

Ý tưởng là tôi có một số mặt hàng, từng liên quan đến một đơn loại và "xuất hiện" nhiều lần. Trường tỷ lệ phải bao gồm phần trăm số lần xuất hiện của mỗi mục trong tổng số lần xuất hiện của các mục trong danh mục.

Trong pseudo-code những gì tôi cần là như sau:

  • Đối với mỗi loại
    tìm ra tổng số lần ra sân cho các hạng mục liên quan đến nó. Ví dụ nó có thể được thực hiện với (select sum("appearances") from table group by category)

  • Đối với mỗi mục
    thiết lập giá trị tỷ lệ như sự xuất hiện của mục chia cho tổng tìm thấy cho hạng mục trên

Bây giờ tôi cố gắng để đạt được điều này với một truy vấn cập nhật duy nhất, nhưng dường như không thể làm điều đó. Những gì tôi nghĩ tôi nên làm là:

update Table T  
set T.ratio = T.appearances/ 
( 
select sum(S.appearances)  
from Table S  
where S.id = T.id  
) 

Nhưng MySQL không chấp nhận bí danh T trong cột cập nhật và tôi không tìm cách khác để đạt được điều này.

Bất kỳ ý tưởng nào?

Trả lời

45

Sau hai câu trả lời tôi nhận được (không ai trong số đó đã hoàn thành nên tôi đã viết của riêng tôi), những gì tôi cuối cùng đã làm là như sau:

UPDATE Table AS target 
INNER JOIN 
(
select category, appearances_sum 
from Table T inner join (
    select category as cat, sum(appearances) as appearances_sum 
    from Table 
    group by cat 
) as agg 
where T.category = agg.cat 
group by category 
) as source 
ON target.category = source.category 
SET target.probability = target.appearances/source.appearances_sum 

Nó hoạt động rất nhanh. Tôi cũng đã thử với truy vấn con tương quan nhưng nó chậm hơn nhiều (thứ tự độ lớn), vì vậy tôi gắn bó với sự tham gia.

+0

Vui lòng gắn cờ câu trả lời là câu trả lời để câu hỏi này bị xóa khỏi danh sách câu hỏi chưa được trả lời :) –

+1

@Frans: Tôi phải chờ 48 giờ trước khi tôi có thể làm như vậy, quy tắc ngăn xếp chồng chéo :) –

+0

Rất tốt. Cảm ơn bạn đã dành thời gian để cung cấp một ví dụ đầy đủ! – Ben

3

Đây là cách nó được thực hiện trong MSSQL, tôi nghĩ rằng mysql là như nhau hoặc tương tự:

create table T (id int, ratio float, appearances int) 
insert T values (1, null, 2) 
insert T values (1, null, 3) 

update T 
set ratio = cast(appearances as float)/ agg.appearancesSum 
from T join (
    select id, sum(appearances) as appearancesSum 
    from T 
    group by id 
) as agg on t.id = agg.id 
+0

Xin lỗi, điều này không hoạt động trong MySQL. Tôi không bỏ phiếu vì nó chắc chắn nó hoạt động trên mssql ... –

6

Sử dụng tham gia ngay sau khi UPDATE: Reference Manual – 13.2.11 UPDATE Syntax

nên CẬP NHẬT table1 bên tham gia table2 trên. ... đặt table1.foo = value trong đó table2.bla = someothervalue

Với những thứ như vậy, hãy luôn xem hướng dẫn. MySql có một tài liệu tham khảo thích hợp, do đó, nó không phải là khó để có được cú pháp đúng;)

+0

Cảm ơn, tôi sẽ thử nó ngay khi có thể. Và bằng cách này - tôi đã làm RTFM và thử mọi thứ có ý nghĩa trước khi đăng câu hỏi :) –

+0

cảm ơn, mục nhập thủ công đã làm rõ cho tôi giải pháp.tích cực cho bạn cũng –