2017-08-28 15 views
5

Các lời xin lỗi cho tiêu đề nhưng tôi đang cố gắng thực hiện công việc trên mức của tôi ngay cả khi tôi giải thích nó.Máy chủ SQL - Cố gắng khử chuẩn hóa bảng của tôi

Nói rằng tôi có một bảng với các biến người, thực phẩm và số tiền:

Person food  Amount 
Mike Butter 3 
Mike Milk  4 
Mike Chicken 2 
Tim  Milk  4 
John Chicken 2 

Bằng cách tham gia bảng với chính nó trong các truy vấn tôi đã được quản lý để thực hiện một danh sách mà thực phẩm là cơ sở cho các biến mới và giá trị là số tiền. Bảng trên sẽ trở thành:

Person Butter Milk Chicken 
Mike 3  4 2 

Mã này là xấp xỉ:

Select 
    a.person, 
    b.amount as Butter, 
    c.amount as Milk, 
    d.amount as Chicken 
from PersonFoodAmount a 
inner join PersonFoodAmount b on a.person = b.person 
inner join PersonFoodAmount c on a.person=c.person 
where b.food='Butter' 
and c.food='Milk' 
and d.food='Chicken' 

Bây giờ, điều này mang lại cho tôi Mike bởi vì anh ta sẽ kiểm tra tất cả các hộp ra. Nhưng tôi cũng cần có các kết quả khớp một phần:

Person Butter Milk Chicken 
Mike 3  4 2 
Tim  NULL 4 NULL 
John NULL Null 2 

Tôi đã thử tất cả các loại tham gia, kể cả tham gia toàn bộ bên ngoài nhưng tôi vẫn chỉ nhận được những người có tủ lạnh đầy đủ.

Mọi đề xuất?

+3

bạn cần phải sử dụng sql trục ... –

Trả lời

6

Bạn có thể sử dụng Pivot để thực hiện việc này.

DECLARE @PersonStuff TABLE (Person varchar(10), Food varchar(10), Amount INT) 

INSERT INTO @PersonStuff VALUES 
('Mike','Butter', 3), 
('Mike','Milk', 4), 
('Mike','Chicken', 2), 
('Tim','Milk', 4), 
('John','Chicken', 2) 

SELECT 
    * 
FROM ( 
    SELECT 
     * 
    FROM @PersonStuff) AS SourceTable 
PIVOT ( 
    AVG(Amount) 
    FOR Food IN ([Butter],[Milk],[Chicken]) 
) AS PivotTable 

Kết quả:

Person Butter Milk Chicken 
John NULL NULL 2 
Mike 3  4  2 
Tim  NULL 4  NULL 
+0

Điều này có vẻ giống như con đường để đi, cảm ơn bạn. Nhưng với những vấn đề phức tạp hơn nữa, "sữa" thực sự là một số con số đi vào danh mục "sữa". Tôi đang cố gắng sử dụng "cho survey_detail_id trong ([('184', '202', '235', '253', '325', '359', '377') dưới dạng tilfreds]" như là viết tắt của "FOR Food IN ([Butter] "nhưng tôi nhận được:" Giá trị không chính xác "('184', '202', '235', '253', '325', '359', '377') dưới dạng tilfred" là được cung cấp trong nhà điều hành PIVOT. " – user2523167

+0

Bạn nên viết các giá trị như thế này ([184], [202], [235], [253], [325], [359], [377]) –

+0

Nhưng tôi có thể để recode nhiều số ** AS ** một biến, tilfreds (/ sữa)? Nó trông giống như cách bạn viết nó tôi sẽ nhận được một biến riêng biệt cho mỗi số? ("bảy thực phẩm khác nhau")? – user2523167

5

tôi sẽ đề nghị một cái gì đó tốt hơn, tập hợp điều kiện:

SELECT t.person, 
     MAX(CASE WHEN t.food = 'Butter' THEN t.amout END) as Butter, 
     MAX(CASE WHEN t.food = 'Milk' THEN t.amout END) as Milk, 
     MAX(CASE WHEN t.food = 'Chicken' THEN t.amout END) as Chicken 
FROM PersonFoodAmount t 
GROUP BY t.person 

Bằng cách đó, bạn không cần phải tham gia vào bảng 3 lần để bản thân. Ngoài ra, tôi thấy bài viết này dễ đọc hơn một lần để hiểu nó.

+0

Operand kiểu dữ liệu NULL không hợp lệ cho nhà khai thác tối đa. –

+4

Max hoạt động tốt trên các cột không có giá trị. – sagi

+0

@sagi tại sao, hoặc khi nào, liệu một người có thể sử dụng giải pháp của bạn qua PIVOT không? – Eli

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