我正在尝试为关键字搜索编写存储过程。我们设置数据库的方式。
有一个Genres
表格有Genre names
和Genre ID's
,然后有一个Genrebridge
表,其中包含genreID1, GenreID2, GenreID3, GenreID4, GenreID5, SongID, AlbumID
和ArtistID
。
如何内部加入每个GenreID
字段,以便Genre name
链接到Genre Bridge
表
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 :(得分:5)
除了使用注释中提到的相同别名外,表GenreBridge
未正确标准化。要规范化表格,最好在表格上放置一个GenreID
列,然后根据需要插入尽可能多的行来模拟专辑的所有类型。这也将解除对每张专辑类型数量的任意限制。
作为附注,您的原始程序似乎根本不使用Genre
(在选择列表或过滤器中),因此无需加入它,您将不需要DISTINCT
。
正如您所注意到的,您现在面临联接问题,具体取决于AlbumGenre
假设你一直使用INT主键,我会将表GenreBridge
规范化为Albums和Genres之间的很多:很多链接表,同时将它重命名为AlbumGenre
反映了许多:许多惯例,例如:
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)
);
您的程序需要强制执行1到5种类型的限制(即在插入AlbumnGenre
记录链接之前,确保此列的行少于5行。)
要列出相册的所有类型,您只需要将Albumn
加入AlbumGenre
并在where子句中按AlbumnId
过滤(它将返回尽可能多的行数)是流派)。
如上所述,不需要DISTINCT
或加入流派:
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
答案 1 :(得分:1)
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 + '%')