2010-02-16 84 views
3

目前我有2台如何在T-SQL/Linq中查询这个复杂的查询?

[Category] -> PK| CAT_ID -> CAT_PARENT (link to itself | if it's a top parent category then it's 0) 
[Posts] -> PK | POST_ID -> FK | CAT_ID | CREATE_DATE 

如何在其中有多个孩子每类选择CAT_PARENT帖子的前15行。因此,CAT_PARENT中的所有帖子及其所有子帖子都只有15个。我们在此处有多个CAT_PARENT。所以我们可以返回包含每个CAT_PARENT 15个帖子的多个帖子组以及它的子类别

这里的问题是将它一次往返查询到SQL服务器,因为一个查询最多可能需要200个帖子如果你可以在1个T-sql查询/ linq查询中编写它,它可能是最好的。

我更喜欢,如果你可以写在LINQ。但也可以在T-SQL中编写它。

非常感谢你:)


由于亚历山大的解决方案到这里,我修改了一些部分,并将其与186查询和一些延迟加载列好工作了不到2秒(远程)到我的SQL服务器

ALTER procedure [dbo].[get_topParentPost] (
    @quantity int 
) 
as 
    WITH t AS (
    SELECT ROW_NUMBER() OVER (PARTITION BY top_level.CAT_ID ORDER BY p.CREATE_DATE DESC) AS row_num, 
    top_level.CAT_ID AS top_level_cat_id, child_category.CAT_ID AS category_id, p.POST_ID, p.CREATE_DATE, p.VALIDATE, 
    p.CAT_ID, p.DESCRIPTION, p.DRAF_OF, p.END_DATE, p.MOD_DATE, p.ON_HOMEPAGE, p.PUBLISH_DATE, p.[STATE], p.THUMB_ID, p.TITLE, p.[TYPE], 
    p.[VIEW] 
    FROM 
     (SELECT cat_id, 0 as cat_parent FROM Categories c WHERE CAT_PARRENT = 0) AS top_level 
     INNER JOIN Categories AS child_category 
      ON child_category.CAT_PARRENT = top_level.CAT_ID OR child_category.CAT_ID = top_level.CAT_ID 
     INNER JOIN Posts p 
      ON child_category.CAT_ID = p.CAT_ID AND p.VALIDATE = 1 
    ) 
    SELECT * FROM t WHERE row_num <= @quantity 

我修改了一些部分,这有助于查询按降序日期,而不是ID上升

+2

什么是帖子表有问题的事,给您的查询和模式? – 2010-02-16 01:32:09

+0

对不起,我忘了包括一些东西 – DucDigital 2010-02-16 01:35:11

+0

我已经添加了这个问题的详细信息。 – DucDigital 2010-02-16 01:37:31

回答

1

如果:

这个脚本从帖子表,其类别有超过1子类别选择前15项它是SQL Server 2005或更高版本,可以这样做:

SELECT t.top_level_cat_id, t.category_id, t.post_id, t.post_date 
FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY top_level.cat_id ORDER BY p.post_id) AS row_num, 
     top_level.cat_id AS top_level_cat_id, 
     child_category.cat_id AS category_id, 
     p.post_id, 
     p.post_date 
    FROM 
     Post p 
     INNER JOIN Category AS child_category 
     ON child_category.cat_id = p.cat_id 
     INNER JOIN Category AS top_level 
     ON top_level.cat_id = child_category.cat_parent 
) AS t 
WHERE t.row_num <= 15 

这里的T-SQL我用来创建测试表:

CREATE TABLE Category (cat_id INT, cat_parent INT); 
--top level 
INSERT INTO Category VALUES(1, 0); 
INSERT INTO Category VALUES(2, 0); 
-- child categories 
INSERT INTO Category VALUES(3, 1); 
INSERT INTO Category VALUES(4, 1); 
INSERT INTO Category VALUES(5, 2); 

CREATE TABLE Post(post_id INT, cat_id INT, post_date DATETIME); 
INSERT INTO Post VALUES(1, 3, GETDATE()); 
INSERT INTO Post VALUES(2, 3, GETDATE()); 
INSERT INTO Post VALUES(3, 3, GETDATE()); 
INSERT INTO Post VALUES(4, 3, GETDATE()); 
INSERT INTO Post VALUES(5, 3, GETDATE()); 
INSERT INTO Post VALUES(6, 3, GETDATE()); 
INSERT INTO Post VALUES(7, 3, GETDATE()); 
INSERT INTO Post VALUES(8, 3, GETDATE()); 
INSERT INTO Post VALUES(9, 3, GETDATE()); 
INSERT INTO Post VALUES(10, 3, GETDATE()); 
INSERT INTO Post VALUES(11, 3, GETDATE()); 
INSERT INTO Post VALUES(12, 3, GETDATE()); 
INSERT INTO Post VALUES(13, 3, GETDATE()); 
INSERT INTO Post VALUES(14, 3, GETDATE()); 
INSERT INTO Post VALUES(15, 3, GETDATE()); 
-- these records won't appear 
INSERT INTO Post VALUES(16, 3, GETDATE()); 
INSERT INTO Post VALUES(17, 4, GETDATE()); 
INSERT INTO Post VALUES(18, 4, GETDATE()); 

INSERT INTO Post VALUES(19, 5, GETDATE()); 
INSERT INTO Post VALUES(20, 5, GETDATE()); 
+0

感谢您的解决方案,我发现了一种在我自己的查询中实现这一点的方法。我创建了一个存储过程,它工作得很好。 :P – DucDigital 2010-02-16 08:34:24

1

我不知道选择前15名,如果有任何的方式来做到THI与LINQ没有牵扯更多的信息,但这里是一个T-SQL脚本,将完成任务。只是为了确保我了解的要求,这里是我的脚本的描述:

declare @cat_id int 
declare MULTIPLE_CHILDREN_CATEGORIES cursor for 
(
    select cat_id 
    from categories 
    group by cat_parent 
    having count(*) > 1 
) 

open MULTIPLE_CHILDREN_CATEGORIES 
fetch next from MULTIPLE_CHILDREN_CATEGORIES into @cat_id 

while @@fetch_status = 0 
begin 
    select top 15 * 
    from posts 
    where cat_id = @cat_id 
    order by create_date desc 

    fetch next from MULTIPLE_CHILDREN_CATEGORIES into @cat_id 
end 

close MULTIPLE_CHILDREN_CATEGORIES 
deallocate MULTIPLE_CHILDREN_CATEGORIES 
0

我想是这样的LINQ2SQL:

IEnumerable<IEnumerable<Post>> posts = db.Categorys 
         .Where(p=>p.CAT_PARENT == 0) 
         .Select(p=>p.Categorys 
          .SelectMany(q=>q.Posts) 
          .OrderByDescending(q=>q.CREATE_DATE) 
          .Take(15))