【发布时间】:2013-05-07 08:55:14
【问题描述】:
我正在尝试从varchar 形式的一个表中获取数据,并将其传递给具有与 int 相同字段的其他查询。
表 Article 包含以下字段
(ArticleID int, ArticleTitle nvarchar(200), ArticleDesc nvarchar(MAX))
样本数据
1 Title1 Desc1
2 Title2 Desc2
3 Title3 Desc3
我有另一个名为 Banner 的表格,其中包含与文章相关的横幅
(BannerID int, BannerName nvarchar(200), BannerPath nvarchar(MAX), ArticleID varchar(200))
样本数据
**BannerID BannerName BannerFile ArticleID**
100 Banner1 BannerPath1 '1','3','5'
101 Banner2 BannerPath2 '2','3','5'
102 Banner3 BannerPath3 '8','3','5'
103 Banner4 BannerPath4 '10','30','5','2','3','5'
示例查询
SELECT ArticleTitle
FROM Article
WHERE CAST(ArticleID AS varchar(200)) IN (
SELECT ArticleID FROM Banner WHERE BannerID = 2
)
在我的实际项目中,我在横幅表中有多个字段,以便我可以分配横幅文章、作者、类别、页面..
出于这个原因,我决定以这种格式将 ArticleID 或 WriteID 或 CatID 存储为单个字段'10','30','5','2','3','5'
我改变了我的结构,然后我可能最终为一个横幅创建数百条记录,一个横幅可以分配给这个article, writer, Category, Pages中的任何一个@
下面的查询返回零行可能是我的投射造成了问题,我将不胜感激如何在不改变我的数据库结构的情况下解决这个问题
SELECT ArticleTitle FROM Article WHERE CAST(ArticleID AS varchar(200)) IN (SELECT ArticleID FROM Banner WHERE BannerID = 2)
更新:
没有冒犯我决定坚持我的设计的任何人,因为我提出的问题是网站的支持报告部分不会经常使用。关于不规范化表格我可能是错的......
我的实际场景假设用户访问url
`abc.com/article/article.aspx?articleID=30&CatID=10&PageID=3&writerID=3`
基于此 url,我可以使用 UNION 运行四个查询,以获得所需的横幅偏离路线我必须决定横幅优先级,所以我会这样做
`SELECT BannerName, BannerImage FROM Banner WHERE ArticleID LIKE '%''30''%'`
UNION ALL
`SELECT BannerName, BannerImage FROM Banner WHERE CategoryID LIKE '%''10''%'`
UNION ALL
`Another query .......`
如果我这样做,那么查询将不得不在单个表中查找带有几行的横幅但如果我根据JW 规范化表,这是一种很好的做法,可能会导致每个横幅有 30-40 行在不同的表格中,这可能会影响性能,因为我必须为新文章(新杂志问题)添加新横幅。
我知道我违反了规范化的每一条法则,但我担心我必须为了性能而这样做,因为我可能最终每 100 个横幅有 2000 行,而且这会随着时间的推移而增长。
再次更新
我希望这张图片能让你大致了解我正在尝试做的事情
如果我这样做,那么每个横幅只需要 1 行,如果我进一步规范化并创建更多表格,那么我最终可能会为一个横幅设置几行 从横幅表中获取上面的图像样本,然后我的第一个横幅将有 27 行 第二条横幅 11 行 三分之二横幅 14 行。
为了避免这种情况,我想在他们尊重的字段中存储多个 articleID、IssueID、PageID ....。这种方法可能很脏,但很有效。
我确实有一些 -ve 反馈,从他们的角度来看是可以理解的。由于我提供了更多详细信息,因此我的方法完全不专业,或者请记住,网站可能有很好的流量并且这种方法可能是更快。
【问题讨论】:
-
是
ArticleID真的保存为'1','3','5'还是1,3,5? -
我在查看问题时做了一个 SQL Fiddle:sqlfiddle.com/#!3/2ee3c/2。无论如何,我建议你接受 JW 在他的回答中给出的建议。
-
我同意 JW 关于规范化的观点,我只是想知道为什么它不起作用。我的 id 以
'1','3','5'存储在数据库中,我可以将其更改为1,3,5。我同意这有一个设计缺陷,但它可以与数百个插入语句相同,因为我的横幅可以与 1)大约 10 个杂志问题和列表可以增长 2)大约 30 个类别。 3) 最多 25- 30 篇文章 4) 作家,随着我们不断添加新的杂志问题,作者可能有数百人 5) 最多 10 个不同的 pageID。 -
它不起作用,因为碰巧包含逗号的 single 字符串值(并且,取决于您尝试的版本,引号)是不一样的作为 multiple int/string 值。我不知道系统会决定检查字符串的内部部分并神奇地将一个值转换为多个值的语言。然而,人们似乎认为 SQL 会以这种方式工作......我同意@JW웃 - 正确规范你的表。
-
“为了表现我必须这样做”可能是我听过的最糟糕的理由之一。您的设计排除了使用索引的可能性如果存在实际性能问题。您显示的
UNION查询别无选择,只能扫描 整个 表以查找每个查询。
标签: asp.net sql-server sql-server-2008 join