2012-04-02 26 views
5

Tôi có một hệ thống được xây dựng trên cơ sở dữ liệu MySQL quan hệ cho phép mọi người lưu trữ chi tiết về "khách hàng tiềm năng". Ngoài ra, mọi người có thể tạo các cột của riêng họ để lưu trữ dữ liệu và sau đó khi thêm tài khoản mới có thể thêm dữ liệu theo họ. Các cấu trúc bảng trông như thế này:Làm cách nào để truy xuất thuộc tính "động" được lưu trữ trong nhiều hàng dưới dạng bản ghi bình thường?

dẫn - id, email, user_id

ĐẶC TÍNH - id, attr_name, user_id

ATTR_VALUES - lead_id, attr_id, giá trị, user_id

Rõ ràng trong các bảng "user_id" này đề cập đến bảng "Người dùng" chỉ chứa những người có thể đăng nhập vào hệ thống.

Tôi đang viết hàm cho chi tiết khách hàng đầu ra và hiện tại chỉ cần kéo chi tiết khách hàng cơ bản làm truy vấn, sau đó kéo qua từng giá trị thuộc tính liên kết với khách hàng tiềm năng đó (tham gia bảng thuộc tính để lấy tên) và sau đó tham gia các mảng trong PHP. Đây là một chút lộn xộn, và tôi đã tự hỏi nếu có một cách để làm điều này trong một truy vấn SQL. Tôi đã đọc một chút về một cái gì đó gọi là một "bảng tổng hợp", nhưng tôi đang đấu tranh để hiểu nó hoạt động như thế nào.

Mọi trợ giúp sẽ được đánh giá cao. Cảm ơn!

+0

MySql không hỗ trợ lệnh Pivot. Eh, nó miễn phí. – McGarnagle

+0

@dbase (microsoft?) Người đàn ông: không * "Eh, nó miễn phí" *, nhưng * "Eh, đó là một cơ sở dữ liệu" * (không giống như ...). Lệnh Pivot không thuộc về cơ sở dữ liệu, nhưng đến cấp bản trình bày. – TMS

+0

Câu hỏi hay, mặc dù tiêu đề gây hiểu lầm - có thể trong một truy vấn đơn giản khá dễ dàng, chỉ cần thường tham gia tất cả các bảng - nhưng đó không phải là những gì bạn có thể muốn. Đã chỉnh sửa tiêu đề. – TMS

Trả lời

0

Tôi sẽ xem cái này link. Đó là giải thích cơ bản của một trục:

"pivot table" hay một "báo cáo crosstab" SQL Chức năng Đặc điểm: Bạn nó mà không có "nếu", "trường hợp", hay "GROUP_CONCAT". Có, có sử dụng cho điều này ... "nếu" tuyên bố đôi khi gây ra vấn đề khi được sử dụng trong sự kết hợp . Bí quyết đơn giản, và đó cũng là lý do tại sao chúng hoạt động trong hầu hết các cơ sở dữ liệu, là các hàm sau: dấu (x) trả về -1,0, +1 cho các giá trị x < 0, x = 0, x> 0 abs tương ứng (dấu (x)) trả về 0 nếu x = 0 else, 1 nếu x> 0 hoặc x < 0 1-abs (dấu (x)) bổ sung của ở trên, vì điều này trả về 1 chỉ khi x = 0

Nó cũng giải thích một cách đơn giản hơn về các bài kiểm tra xoay vòng. Có lẽ điều này có thể làm sáng tỏ nó?

1

Bạn có thể thực hiện xoay vòng trong một truy vấn như sau:

select l.id lead_id, 
     l.email, 
     group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone, 
     ... 
from leads l 
left join attr_values v on l.id = v.lead_id 
left join attributes a on v.attr_id = a.id 
group by l.id 

Bạn sẽ cần phải bao gồm một group_concat lĩnh vực -derived riêng biệt cho mỗi thuộc tính bạn muốn hiển thị.

0

Điều bạn có thể muốn từ mysql là tạo một giá trị sql (attr_name trong trường hợp của bạn) một cột. Nguyên tắc này được gọi là pivot table (đôi khi cũng chéo bảng hoặc truy vấn chéo bảng) và không được hỗ trợ bởi mysql. Không phải vì mysql không đủ, nhưng vì hoạt động trục không phải là hoạt động cơ sở dữ liệu - kết quả không phải là bảng cơ sở dữ liệu bình thường và là không phải được thiết kế cho các hoạt động cơ sở dữ liệu khác.Mục đích duy nhất của hoạt động trục xoay bản trình bày - đó là lý do tại sao nó thuộc về lớp trình bày, không phải cơ sở dữ liệu.

Vì vậy, mọi giải pháp cố gắng lấy bảng tổng hợp từ mysql sẽ luôn bị hacky. Những gì tôi khuyên là để có được các dữ liệu từ cơ sở dữ liệu ở định dạng bình thường, bằng cách đơn giản làm một cái gì đó như:

select * 
from attr_values join attributes using on attr_id = attributes.id 
    join leads on leads.id = lead_id 

và sau đó chuyển đổi đầu ra cơ sở dữ liệu bằng ngôn ngữ trình bày (PHP, JSP, Python hay bất cứ điều gì bạn sử dụng).

0

Tôi sẽ cẩn thận giả định rằng trục xoay sẽ đạt được mục tiêu đơn giản hóa của bạn. Pivot sẽ chỉ hoạt động nếu bạn có tên người quản lý nhất quán. Kể từ khi bạn gắn một userid với nó, tôi giả định nó sẽ không. Ngoài ra, bạn sẽ có nhiều giá trị cho một attr_name. Tôi sợ bảng tổng hợp sẽ không tạo ra kết quả mà bạn đang tìm kiếm.

Tôi khuyên bạn nên giữ riêng các bảng giao dịch và báo cáo của mình. Có một thói quen ETL sẽ làm sạch (ví dụ: làm cho attr_name và attr_value) nhất quán thông qua dịch thuật. Điều này sẽ làm cho báo cáo của bạn có ý nghĩa hơn.

Tóm lại, để xuất ngay lập tức cho người dùng cuối, PHP là cách tốt nhất bạn có thể làm. Để báo cáo, chuyển đổi EAV thành một hàng/cột trước tiên trước khi cố gắng báo cáo về nó.