我的sql数据库中有3个表,如下所示:
Documents : (DocID, FileName) //list of all docs that were attached to items
Items : (ItemID, ...) //list of all items
DocumentRelation : (DocID, ItemID) //the relation between docs and items
在我的winform应用程序中,我在网格视图中显示了 Items 表的所有记录,并让用户选择它的几行,然后如果他按下EditAll按钮,另一个网格视图应该用文件名填充与这些所选项目相关但不是所有项目的文档,
只是与所有所选项目有关的每个文件
是否有任何查询( sql或linq )来选择这些文件?
答案 0 :(得分:1)
尝试类似:
string query;
foreach (Item in SelectedItems)
{
query += "select DocID from DocumentRelation where ItemID =" + Item.Id;
query += "INTERSECT";
}
query -= "INTERSECT";
执行查询;
答案 1 :(得分:1)
取一个字符串并继续添加itemid逗号分隔,如1,2,3然后编写查询
declare ItemID varchar(50);
set ItemID='1,2,3';
select FileName
from documents
Left Join DocumentRelation on Documents.DocId = DocumentRelation.DocId
where
DocumentRelation.ItemID in (select * from > dbo.SplitString(ItemID))
然后在数据库中创建一个函数,如下所示
ALTER FUNCTION [dbo].[SplitString] (@OrderList varchar(1000))
RETURNS @ParsedList table (OrderID varchar(1000) )
AS BEGIN
IF @OrderList = ''
BEGIN
set @OrderList='Null'
end
DECLARE @OrderID varchar(1000), @Pos int
SET @OrderList = LTRIM(RTRIM(@OrderList))+ ','
SET @Pos = CHARINDEX(',', @OrderList, 1)
IF REPLACE(@OrderList, ',', '') <''
BEGIN
WHILE @Pos 0
BEGIN
SET @OrderID = LTRIM(RTRIM(LEFT(@OrderList, @Pos - 1)))
IF @OrderID < ''
BEGIN
INSERT INTO @ParsedList (OrderID)
VALUES (CAST(@OrderID AS varchar(1000)))
--Use Appropriate conversion
END
SET @OrderList = RIGHT(@OrderList, LEN(@OrderList) - @Pos)
SET @Pos = CHARINDEX(',', @OrderList, 1)
END
END
RETURN
END
答案 2 :(得分:0)
LINQ的
var td =
from s in Items
join r in DocumentRelation on s.ItemID equals r.ItemID
join k in Documents on k.DocID equals r.DocID
where Coll.Contains (s.ItemID) //Here Coll is the collection of ItemID which you can store when the users click on the grid view row
select new
{
FileName=k.FileName,
DocumentID= k.DocId
};
您可以遍历td集合并绑定到网格视图
SQL
创建存储过程以获取从网格视图中选择的itemID的相关文档,并参数化您的in子句
select k.FileName,k.DocId from Items as s inner join
DocumentRelation as r on
s.ItemID=r.ItemID and r.ItemId in (pass the above coll containing selected ItemIds as an input the SP)
inner join Documents as k
on k.DocId=r.DocIk
上获取相关信息
答案 3 :(得分:0)
这是一种方法。我会告诉你如何提供作为参数的项目列表。我还假设(DocID,ItemID)是关系表中的主键。 having
条件强制要求所有选择项与您正在寻找的文档列表相关。
;with ItemsSelected as (
select i.ItemID
from Items as i
where i.ItemID in (<list of selected ItemIDs>)
)
select dr.DocID
from DocumentRelation as dr
where dr.ItemID in (select ItemID from ItemsSelected)
group by dr.DocID
having count(dr.ItemID) = (select count(*) from ItemsSelected);
修改强>
据我所知,尽管OP的评论如下,但已接受的答案相当于此处的解决方案。
我使用了很长的一系列intersect
查询进行了一些快速测试,并确认您确实可以期望随着所选项目数量的增加,这种方法逐渐变慢。但更糟糕的问题是编译查询所花费的时间。我在一个非常快的服务器上尝试了这个,并且发现当大约一百个交叉连接时,该步骤大约需要8秒。
在产生此错误之前,SQL Fiddle没有让我在任何地方附近做任何事情(并且在此过程中花费的时间超过十秒):查询处理器耗尽了内部资源,无法生成查询计划。这是一种罕见的事件,仅适用于引用大量表或分区的极其复杂的查询或查询。请简化查询。如果您认为自己错误地收到了此消息,请与客户支持服务部门联系以获取更多信息。
将参数列表传递给SQL Server有几种可能的方法。假设您更喜欢动态查询解决方案,我认为此版本仍然更好,同时还注意到in
内的值数量存在SQL Server限制。
有很多方法可以让这些东西爆炸。