2015-05-05 16 views
7

Tôi đang cố gắng viết một thủ tục lưu sẵn để tìm kiếm từ khóa. Cách chúng tôi thiết lập DB của mình.Làm cách nào để tham gia nhiều cột?

Có một bảng GenresGenre namesGenre ID's, sau đó là một bảng Genrebridge trong đó có genreID1, GenreID2, GenreID3, GenreID4, GenreID5, SongID, AlbumIDArtistID.

Làm thế nào để bên tham gia mỗi GenreID lĩnh vực, do đó Genre name được liên kết với Genre Bridge bảng

ALTER PROCEDURE [dbo].[usp_album_search_keyword_AlbumNameANDArtistName] 
(
    -- Add the parameters for the stored procedure here 
    @albumname varchar(255), 
    @artistname varchar(255) 
) 
As 
Begin 
Select 
    Distinct a.AlbumTitle, art.ArtistName, a.AvgRatingNBR, a.OriginalPrice, a.DiscountPrice 
FROM 
    Albums a 
    inner join Artists art on a.ArtistID = art.ArtistID 
    inner join GenreBridge gb on gb.AlbumID = a.AlbumID 
    inner join Genres g on g.GenreID = gb.GenreID1 
    inner join genres g on g.GenreID = gb.genreID2 
    inner join genres g on g.GenreID = gb.GenreID3 
    inner join genres g on g.GenreID = gb.GenreID4 
    inner join genres g on g.GenreID = gb.GenreID5 

    where a.AlbumTitle like '%' + @albumname + '%' 
    and art.ArtistName like '%' + @artistname + '%' 
End 
+0

Mã này có chạy không? Và, nếu có, bạn nhận được kết quả gì? –

+0

khi tôi thử và thực hiện thủ tục, tôi nhận được lỗi sau: Tên đối tượng không hợp lệ 'g'. chỉnh sửa: tôi tin rằng lần thứ hai tôi tuyên bố thể loại là g – Parth

+4

sử dụng các bí danh khác thay vì 'g', như' g1', 'g2', v.v. – cha

Trả lời

5

khác so với sử dụng các bí danh tương tự như đã nêu trong các ý kiến, bảng GenreBridge không phải là chính xác chuẩn hóa. Để bình thường hóa bảng, sẽ tốt hơn nếu có một cột GenreID duy nhất trên bảng và sau đó chèn nhiều hàng nếu cần để mô hình tất cả các thể loại của một album. Điều này cũng sẽ nâng mức giới hạn tùy ý lên số lượng thể loại cho mỗi album.

Lưu ý, thủ tục ban đầu của bạn dường như không sử dụng Genre ở tất cả (trong danh sách lựa chọn hoặc bộ lọc), do đó không cần tham gia và bạn sẽ không cần DISTINCT.

Như bạn đã biết, bạn đang phải đối mặt với vấn đề tham gia tùy thuộc vào số lượng các cột thể loại hợp lệ có mặt trên AlbumGenre

Giả sử bạn đã sử dụng INT khóa chính trong suốt, tôi sẽ bình thường hóa bảng GenreBridge trở thành một nhiều: nhiều bảng liên kết giữa Albums và thể loại, và đồng thời đổi tên nó AlbumGenre để phản ánh tốt hơn nhiều: nhiều quy ước, ví dụ:

CREATE TABLE dbo.AlbumGenre 
(
    AlbumId INT NOT NULL, 
    GenreId INT NOT NULL, 

    CONSTRAINT PK_AlbumnGenre PRIMARY KEY(AlbumId, GenreId), 
    CONSTRAINT FK_AlbumnGenre_Albumn FOREIGN KEY(AlbumId) REFERENCES Albums(AlbumId), 
    CONSTRAINT FK_AlbumnGenre_Genre FOREIGN KEY(GenreId) REFERENCES Genres(GenreId) 
); 

các hạn chế đó có thể có từ 1 đến 5 thể loại sẽ cần phải được chương trình của bạn thực thi (ví dụ: trước khi chèn AlbumnGenre liên kết hồ sơ, đảm bảo rằng có ít hơn 5 hàng cho albumn này.)

Để liệt kê tất cả các thể loại của một album, bạn sẽ chỉ cần tham gia Albumn đến AlbumGenre và lọc theo AlbumnId trong mệnh đề where (nó sẽ trả về nhiều hàng vì có nhiều thể loại).

Như đã đề cập, không cần DISTINCT hoặc tham gia vào thể loại:

ALTER PROCEDURE [dbo].[usp_album_search_keyword_AlbumNameANDArtistName] 
(
    -- Add the parameters for the stored procedure here 
    @albumname varchar(255), 
    @artistname varchar(255) 
) 
As 
Begin 
Select a.AlbumTitle, art.ArtistName, a.AvgRatingNBR, a.OriginalPrice, a.DiscountPrice 
FROM 
    Albums a 
    inner join Artists art on a.ArtistID = art.ArtistID 
    where a.AlbumTitle like '%' + @albumname + '%' 
    and art.ArtistName like '%' + @artistname + '%' 
End 
+0

vì vậy tôi sẽ cần phải có 3 bảng cầu riêng biệt trong kịch bản này, đúng không? – Parth

+0

Không, chỉ một bảng 'AlbumGenre'. Nếu một album có 3 thể loại, thì sẽ có 3 hàng trong 'AlbumGenre' cho cùng một' AlbumId'. Tham gia 'once' giữa 'Album' và' AlbumGenre' và 'Genre' và lọc theo' Album.AlbumId' sẽ có 3 hàng. – StuartLC

+0

xin lỗi, câu hỏi của tôi là mơ hồ. @stuartLC, tôi tin rằng tôi sẽ cần phải tạo một bảng SongGenre và bảng ArtistGenre trong db của tôi và liên kết theo cách tương tự như bạn mô tả ở trên, Trước đây tôi đã cố gắng có một bảng cầu với các trường sau: GenreID \t SongID \t AlbumID \t ArtistID. Đây có phải là thiết kế db xấu không? – Parth

1

@StuartLC đưa ra một số thông tin phản hồi tốt mà tôi sẽ nghiêm túc xem xét. Nhưng nếu bạn định rời khỏi lược đồ cơ sở dữ liệu của mình, truy vấn này sẽ hoạt động:

SELECT   a.AlbumTitle, 
       art.ArtistName, 
       a.AvgRatingNBR, 
       a.OriginalPrice, 
       a.DiscountPrice, 
       g1.GenreName, 
       g2.GenreName, 
       g3.GenreName, 
       g4.GenreName, 
       g5.GenreName 
FROM   Albums a 
INNER JOIN  Artists art on a.ArtistID = art.ArtistID 
INNER JOIN  GenreBridge gb on gb.AlbumID = a.AlbumID 
LEFT OUTER JOIN Genres g1 on g1.GenreID = gb.GenreID1 
LEFT OUTER JOIN Genres g2 on g2.GenreID = gb.GenreID2 
LEFT OUTER JOIN Genres g3 on g3.GenreID = gb.GenreID3 
LEFT OUTER JOIN Genres g4 on g4.GenreID = gb.GenreID4 
LEFT OUTER JOIN Genres g5 on g5.GenreID = gb.GenreID5 
WHERE   a.AlbumTitle like ('%' + @albumname + '%') 
    AND   art.ArtistName like ('%' + @artistname + '%') 
+1

cảm ơn raj! Tôi vừa thảo luận xong với nhóm của mình, chúng ta sẽ theo dõi mô hình của @ stuartLC và chuẩn hóa bảng. – Parth

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