SQL - 选择具有多个类别的不同行

标签 sql sql-server-2008 razor

我有三个数据库表:

故事

  • 身份证
  • 标题
  • 内容

类别

  • 身份证
  • 标题

故事类别

  • 故事 ID
  • 类别ID

注意:故事和类别是多对多的关系(一个故事可以有多个类别,一个类别可以有多个故事),所以我创建了 StoryCategory。此外,故事不能有类别。

我还有一个网页(我使用的是 razor):

<form action="" method="get">
    <label for="keyword">Keyword:</label>
    <input name="keyword" type="text" value="@Page.Keyword" />
    <label for="category">Category:</label>
    <select name="category">
        <option value="">All</option>
    @foreach(var category in Page.Categories)
    {
        <option <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="255344495040186546445140424a575c0b6c41" rel="noreferrer noopener nofollow">[email protected]</a> @(category.Id == Page.Category? "selected=selected" : "")>@category.Title</option>
    }
    </select>
    <input type="submit" value="Search" />
</form> 

为了简单起见,该页面允许用户输入关键字来搜索特定的故事,还允许用户选择故事所属的类别。

我找不到找到附加到特定类别的故事的方法。这是我的第一个代码(忽略关键字以专注于类别):

select s.title --columns will be added here such as name of category/ies, author etc.
from story as s
left join --left join so the uncategorized stories will not be excluded
storyCategory as sc
on s.id = sc.storyId
where sc.categoryId = @selectedCategory --this line is removed when there is no category selected

示例数据:

  • 故事

    id 标题内容 1 火影忍者... 2漂白剂...

  • 类别

    id 标题 1 幻想 2 行动 3话剧

  • 故事类别

    故事 ID 类别 ID 1 1 1 2 2 1

问题是,如果没有选择类别,并且故事有多个类别,它也会出现多次:

naruto (fantasy)
naruto (action)
bleach (fantasy)

我实际上知道发生了什么,但我想不出解决问题的最佳方案。

最佳答案

使用 DISTINCT 关键字,左连接对于 WHERE 条件没有用

select DISTINCT
  s.title --columns will be added here such as name of category/ies, author etc.
from story as s
join storyCategory as sc--left join so the uncategorized stories will not be excluded
on s.id = sc.storyId
where sc.categoryId = @selectedCategory --this line is removed when there is no category selected

如果您需要每个故事附加的类别列表 - 请参阅并检查下一个查询。对 SQL Server 有效:

DECLARE @Stories TABLE(Id INT IDENTITY PRIMARY KEY, NAME NVARCHAR(100) NOT NULL) 
DECLARE @Categories TABLE(Id INT IDENTITY PRIMARY KEY, NAME NVARCHAR(100) NOT NULL) 
DECLARE @Fork TABLE(StoryId INT NOT NULL, CategoryId INT NOT NULL, PRIMARY KEY(StoryId, CategoryId)) 

INSERT @Stories 
VALUES ('Story1'), ('Story2'), ('Story3') 

INSERT @Categories 
VALUES ('Category1'), ('Category2'), ('Category3') 

INSERT @Fork 
VALUES(1,1), (1,2), (3,3), (2,3) 

DECLARE @selectedCategory INT = 3 

select 
s.NAME, 
( 
SELECT c.Name + ',' 
FROM @Categories c 
JOIN @Fork f ON f.CategoryId = c.Id AND f.StoryId = s.Id 
ORDER BY c.Name 
FOR XML PATH('') 
) Categories 
from @stories s

关于SQL - 选择具有多个类别的不同行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8814775/

相关文章:

razor - 带有 Razor (.cshtml) 模板的电子邮件发件人库。 .net 核心 2.0

sql - 查询以按日期列表返回匹配或最近的先前记录

SQL 空值内连接

sql - Varchar 上的索引?

SQL XML Xquery 在节点选择中使用变量进行数据查询?

c# - 无法识别的属性 'targetFramework'。请注意,属性名称区分大小写

vb.net - 在本地 IIS 安装上部署 .vbhtml

sql - 如何在plpgsql中使用变量作为字段类型?

sql - 使用更新表中的聚合的 AFTER UPDATE 触发器

visual-studio-2010 - 如何查找 SQL Server Management Studio 的服务器名称