2014-01-22 209 views
0

可以说,这里是我的数据库结构SQL - 多个查询或一个连接

TableA 
{ 
    [ID] INT IDENTITY (1, 1) primary key, 
    [Title] varchar (50) NOT NULL, 
    [Details] varchar(50) NOT NULL 
} 

TableB: 
{ 
    [ID] INT foreign key references [TableA] ([ID]) 
    [AvailableTime] DATETIME NOT NULL 
} 

TableC: 
{ 
[ID] INT foreign key references [TableA] ([ID]) 
[AvailableLocation] varchar(50) NOT NULL 
} 

我需要所有从表A柱以及特定ID

从表B AvailableTimes列表结果应该如下所示:新对象(id,title,details,List availableTime);

一个ID可能有多个可用时间。性能明智和速度明智的会更好,如果我做两个单独的查询来检索这些信息或做一个连接,然后循环通过列表两次。 I.E.

select * from TableA where ID = 1; 
select * from TableB where ID = 1; 
select * from TableC where ID = 1; 

...

OR

select * from TableA inner join TableB on TableA.ID = TableB.ID inner join TableC on TableA.ID = TableC.ID where ID = 1 
List<DateTime> availableTime = new List<DateTime>(); 
foreach(DataRow row in resultTable.Rows) 
{ 
    if (!availableTime.Contains((DateTime) row["AvailableTime"])) 
     availableTime.Add((DateTime) row["AvailableTime"]); 
} 

foreach(DataRow row in resultTable.Rows) 
{ 
    if (!availableLocation.Contains((string) row["AvailableTime"])) 
     availableLocation.Add((string) row["AvailableLocation"]); 
} 
return new object (id, resultTable.Rows[1], resultTable.Rows[2], availableTime, availableLocation); 

我的服务器上做这个(ASP.NET)和服务器负责对运行查询和前处理数据发送给用户。

在此先感谢。

+2

这将是更方便地提供正确的答案和帮助,如果你可以分享你的表架构 – Tommassiov

+0

运行查询和看看哪一种更好。有时运行两个简单的查询比一个复杂的查询要好。这一切都取决于,而且很难用所给的信息来说。你必须测试它。 –

+0

你需要做的客户端处理在两种情况下获得一个“树”了SQL的。 SQL返回*表格*数据。在C#中,这样的转换(同时保留单个查询)对于LINQ来说是微不足道的。 – user2864740

回答

0

无论是哪种情况,都需要在客户端上执行处理,以便从SQL中获取“树”。 SQL返回表格未标准化的数据。


明智的性能和速度明智的,它会更好,如果我做的两个单独的查询检索这些信息,或者做一个连接,然后遍历列表两次?

通常,在SQL中进行连接更快,更容易。在代码中手动循环SQL选择是有效地使RA无用的一种方式,因为任何散列/合并连接都变为“嵌套循环”。

由于C#支持LINQ这样的转换,这是我的“第一选择” - 好吧,首先在使用真正的LINQ到数据库提供程序之后 - 来处理这种情况。

采取查询(在那里我已经改名为“ID”为理智):

SELECT i.item_id, i.title, i.details, t.available_time 
FROM items i 
JOIN times t ON t.item_id = i.item_id 

的加盟形式将返回一组结果-的(item_id, title, details, available_time)

现在将查询结果读入“readItems”的集合中,使得类型符合IEnumerable<{of the same fields as above}>,然后从数据重建树结构。

var items = readItems 
    // The group by "re-normalize" on the key and the selector 
    // is still key on RS - as the title/details are FDs on item_id 
    .GroupBy(i => new { i.item_id, i.title, i.details }) 
    .Select(g => new ItemWithTimes { 
     ItemId = g.Key.item_id, 
     Title = g.Key.title, 
     Details = g.Key.details, 
     // capture collected data 
     AvailableTimes = g, 
    }); 

当然,如果您使用LINQ到SQL/EF提供商(而不是上述的想象LINQ到对象),则可以跳过手动经历平坦“readItems” result-组。


也有一些例外,一般用超非归结果集,其中多个查询可能更合适 - 这通常会影响非常深树木或当“大”列复制。

此外,像SQL Server的一些数据库支持XML,它可以处理超非归一化的结果集(又名树),而无需经过平表格结果集。

在任何情况下,你会知道你需要做这在时机成熟时 - 并保持清洁DAL(而不是泄露访问所有的地方)将改变实现比较琐碎。

+0

我还可以做同样的事情,如果我有一个第三张表,我想要一个数据列表 – Steve

+0

@Steve Sure [你只需进一步将组值设置在适当的键上],但是你进入“深”树的领域,并交易更多的服务器效率(RA联合),以降低客户端效率(尽管group-by可能是hash-join操作)。有一些临界点和维护点。我通常只是让LINQ2SQL为我做所有的辛苦工作。老实说,在很多情况下,这并不重要 - 它在哪里,这就是我关注的“优化”。 – user2864740

+0

如果服务器必须处理数据,那么该怎么办?因为我正在处理一个asp.net项目 – Steve

0

如果我理解正确的问题,你不需要join都:如果你想删除重复,改变union allunion

select PropertyA 
from tableA 
where id = XXX 
union all 
select PropertyC 
from tableB 
where id = XXX; 

+0

权,工会列。但我仍然想知道哪一个表现更好。 2查询或1 – Steve

+0

@Steve。 。 。两个查询产生了准备查询,编译它们并将它们来回传递到数据库的开销。一个查询应该表现更好。 –

0

的简单连接查询会是这样的

Select A.*, B.AvailableTime 
from TableA A 
inner join TableB B on A.ID=B.ID 

但是你可以通过使用串联到一个逗号分隔字符串

select A.*, (SELECT ', ' + B.AvailableTime 
     FROM TableB B 
     WHERE A.ID=B.ID 
     FOR XML PATH('')) AS Timings 
from TableA A 

避免重复但是,这取决于你的要求,这一个更适合你。

+0

我更关心的是性能和速度,而不是查询本身 – Steve

+0

性能明智的,而不是发送两个结果集的应用程序,并加入有,发送单个ResultSet显然会更快。如果结果集没有重复,则会节省发送更大数据的开销。尝试第二个查询。 – Miller