- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试编写代码以从 SQL Server 数据库中提取产品项目列表并将结果显示在网页上。
该项目的一个需求是在页面右侧显示一个类别列表作为一个复选框列表(默认选中所有类别),用户可以取消选中类别并重新查询数据库以查看产品只属于他们想要的类别。
这里开始变得有点毛茸茸了。
可以使用如下产品类别表将每个产品分配到多个类别...
Product table[product_id](PK),[product_name],[product_price],[isEnabled],etc...Category table[CategoryID](PK),[CategoryName]ProductCagetory table[id](PK),[CategoryID](FK),[ProductID](FK)
我需要选择一个产品列表,这些产品与传递到我的存储过程的一组类别 ID 相匹配,其中产品有多个分配的类别。
类别 ID 作为逗号分隔的 varchar 传递给 proc,即 ( 3,5,8,12 )
SQL 将此 varchar 值分解为临时表中的结果集以供处理。
我将如何编写此查询?
最佳答案
一个问题是将选定类别的数组或列表传递到服务器。 Eland Sommarskog 在系列文章中全面介绍了该主题 Arrays and Lists in SQL Server .将列表作为逗号分隔的字符串传递并构建临时表是一种选择。还有其他选择,例如使用 XML 或表值参数(在 SQL Server 2008 中)或使用表 @variable 而不是 #temp 表。我链接的文章中介绍了各自的优缺点。
现在介绍如何检索产品。首先要做的事情是:如果选择了所有 类别,则使用不同的查询来简单地检索所有产品,而根本不考虑类别。这将节省很多性能,并且考虑到所有用户可能首先会看到一个未选择任何类别的页面,节省的费用可能非常可观。
选择类别 后,构建连接产品、类别和所选类别的查询就相当容易了。使其扩展和执行是一个不同的主题,并且完全取决于您的数据模式和所选类别的实际模式。一个天真的方法是这样的:
select ...
from Products p
where p.IsEnabled = 1
and exists (
select 1
from ProductCategories pc
join #selectedCategories sc on sc.CategoryID = pc.CategoryID
where pc.ProductID = p.ProductID);
ProductsCategoriestable 必须在 (ProductID, CategoryID)
上有一个索引,在 (CategoryID, ProductID)
上有一个索引(其中一个是聚类,一个是 NC)。顺便说一句,对于每个解决方案都是如此。如果始终选择大多数 类别并且结果包含大多数 产品,则此查询将有效。但是,如果所选类别的列表是限制性的,那么最好避免扫描可能较大的产品表并从所选类别开始:
with distinctProducts as (
select distinct pc.ProductID
from ProductCategories pc
join #selectedCategories sc on pc.CategoryID = sc.CategoryID)
select p.*
from Products p
join distinctProducts dc on p.ProductID = dc.ProductID;
同样,最佳解决方案在很大程度上取决于数据的形状。例如,如果您有一个非常倾斜的类别(仅一个类别就涵盖了 99% 的产品),那么最好的解决方案必须考虑到这种倾斜。
关于sql - 多对多选择查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3762704/
SQL、PL-SQL 和 T-SQL 之间有什么区别? 谁能解释一下这三者之间的区别,并提供每一个的相关使用场景? 最佳答案 SQL 是一种对集合进行操作的查询语言。 它或多或少是标准化的,几乎所有关
这个问题已经有答案了: What is the difference between SQL, PL-SQL and T-SQL? (6 个回答) 已关闭 9 年前。 我对 SQL 的了解足以完成我的
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列有一个默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任
我有一个可能属于以下类型的字符串 string expected result 15-th-rp 15 15/12-rp 12 15-12-th
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我有一个存储过程(称为 sprocGetArticles),它从文章表中返回文章列表。这个存储过程没有任何参数。 用户可以对每篇文章发表评论,我将这些评论存储在由文章 ID 链接的评论表中。 有什么方
我目前正在做一个 *cough*Oracle*cough* 数据库主题。讲师介绍embedded SQL作为让其他语言(例如 C、C++)与(Oracle)数据库交互的方式。 我自己做了一些数据库工作
SQL Server 中 SQL 语句的最大长度是多少?这个长度是否取决于 SQL Server 的版本? 例如,在 DECLARE @SQLStatement NVARCHAR(MAX) = N'S
这个问题已经有答案了: Simple way to transpose columns and rows in SQL? (9 个回答) 已关闭 8 年前。 CallType
预先感谢您对此提供的任何帮助。 假设我有一个查询,可以比较跨年的数据,从某个任意年份开始,永无止境(进入 future ),每年同一时期直到最后一个完整的月份(其特点是一月数据永远不会显示至 2 月
我在数据库中有一个 USER 表。该表有一个 RegistrationDate 列,该列的默认约束为 GETDATE()。 使用 LINQ 时,我没有为 RegistrationDate 列提供任何数
下面是我试图用来检查存储过程是否不存在然后创建过程的 sql。它会抛出一个错误:Incorrect syntax near the keyword 'PROCEDURE' IF NOT EXISTS
我有一个同事声称动态 SQL 在许多情况下比静态 SQL 执行得更快,所以我经常看到 DSQL 到处都是。除了明显的缺点,比如在运行之前无法检测到错误并且更难阅读,这是否准确?当我问他为什么一直使用
来自 lobodava 的动态 SQL 查询是: declare @sql nvarchar(4000) = N';with cteColumnts (ORDINAL_POSITION, CO
使用 SQL Server 中的存储过程执行动态 SQL 命令的现实优点和缺点是什么 EXEC (@SQL) 对比 EXEC SP_EXECUTESQL @SQL ? 最佳答案 sp_executes
我有这个有效的 SQL 查询: select sum(dbos.Points) as Points, dboseasons.Year from dbo.StatLines dbos i
我正在调试一些构建成功运行的 SQL 命令的代码。 然而,在查询结束时,查询结果似乎被写入了一个文本文件。 完整的查询如下 echo SELECT DATE,DATETABLE,DATE,APPDAT
我有一些创建表的 .sql 文件(MS SQL 数据库): 表_1.sql: IF OBJECT_ID (N'my_schema.table1', N'U') IS NOT NULL DROP TAB
我写了下面的 SQL 存储过程,它一直给我错误@pid = SELECT MAX(... 整个过程是: Alter PROCEDURE insert_partyco @pname varchar(20
我在 SQL Server 2005 中有包含两列 Fruit 和 Color 的表,如下所示 Fruit Colour Apple Red Orange
我是一名优秀的程序员,十分优秀!