代码之家  ›  专栏  ›  技术社区  ›  DucDigital

如何在T-SQL/LINQ中查询这个复杂的查询?

  •  3
  • DucDigital  · 技术社区  · 14 年前

    目前我有两张桌子

    [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_父级中选择前15行文章。所以在猫咪家长和它的所有孩子的职位总数只有15个。我们这里有多个猫的父母。所以我们可以返回多组post,每个cat_父类和子类包含15个post

    这里的问题是在一次到SQL Server的查询循环中使用它,因为一个查询最多可以占用200个日志,所以如果您可以在1个T-SQL查询/LINQ查询中编写它,那么它可能是最好的。

    我希望你能用linq写。但用T-SQL编写也可以。

    非常感谢:)


    多亏了下面的Alexander解决方案,我修改了一些部分,它可以很好地处理186个查询和一些延迟加载的列(远程地)到我的SQL Server。

    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升序选择前15个

    3 回复  |  直到 14 年前
        1
  •  1
  •   Alex Shirshov    14 年前

    如果是用于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());
    
        2
  •  1
  •   Jake    14 年前

    我不确定是否有任何方法可以在不提取超出必要的信息的情况下使用LINQ来完成这项任务,但是这里有一个T-SQL脚本可以完成这项任务。为了确保我理解需求,下面是我对脚本的描述:

    此脚本从“日志”表中选择前15个条目,该表的类别包含多个子类别:

    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
    
        3
  •  0
  •   Francisco    14 年前

    我想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))