Да, три таблицы - это правильная реализация с внешними ключами между новостями, новой категорией, категорией и новой категорией.
Ваш запрос может выглядеть примерно так, чтобы вернуть все заголовки новостей для определенного имени категории:
SELECT N.Title
FROM news_categories AS NC
INNER JOIN news AS N
ON N.ID = NC.NewsID
INNER JOIN Categories AS C
ON C.ID = NC.CategoryID
WHERE C.Name = @Category
Вы могли бы упростить это, если бы вы уже знали CategoryID, который вы, вероятно, получили бы из выпадающего списка или чего-то еще, тогда таблица Присоединиться к категории будет ненужной, и вы напишите что-то вроде:
SELECT N.Title
FROM news_categories AS NC
INNER JOIN news AS N
ON N.ID = NC.NewsID
WHERE NC.CategoryID = @CategoryID
Чтобы выбрать все новости с их категориями в списке через запятую, вам понадобится пользовательская функция.Вот код SQL, необходимый для помощи с логикой, но фактическая реализация зависит от вас:
CREATE FUNCTION fnCategoryList
(
@NewsID INT
)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @CategoryList VARCHAR(1000)
SET @CategoryList = ''
SELECT @CategoryList = COALESCE(@CategoryList + ',','') + C.[Name]
FROM news_categories AS NC
INNER JOIN categories AS C
ON NC.CategoryID = C.ID
WHERE NC.NewsID = @NewsID
RETURN @CategoryList
END
При использовании вышеуказанного UDF ваш запрос будет выглядеть так:
SELECT Title, fnCategoryList(ID) AS Categories
FROM news
В зависимостина количество записей в вашей таблице новостей, этот запрос не будет работать очень хорошо.Вы должны иметь некоторую форму предложения WHERE почти для каждого запроса, который вы пишете.