Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为每个类别选择前10项记录_Sql_Sql Server_Sql Server 2005_Greatest N Per Group - Fatal编程技术网

Sql 为每个类别选择前10项记录

Sql 为每个类别选择前10项记录,sql,sql-server,sql-server-2005,greatest-n-per-group,Sql,Sql Server,Sql Server 2005,Greatest N Per Group,我想在一个查询中返回每个部分的前10条记录。有人能帮忙做这件事吗?节是表中的一列 数据库是SQLServer2005。我想按输入的日期返回前10名。部分包括业务、本地和功能。对于某个特定日期,我只需要前10个业务行、最近的条目、前10个本地行和前10个功能。操作员是否可以为您工作?为每个部分选择一个,然后将它们合并在一起。不过,我猜它只适用于固定数量的部分。这在SQL Server 2005上起作用,经过编辑以反映您的澄清: select * from Things t where t.Thin

我想在一个查询中返回每个部分的前10条记录。有人能帮忙做这件事吗?节是表中的一列


数据库是SQLServer2005。我想按输入的日期返回前10名。部分包括业务、本地和功能。对于某个特定日期,我只需要前10个业务行、最近的条目、前10个本地行和前10个功能。

操作员是否可以为您工作?为每个部分选择一个,然后将它们合并在一起。不过,我猜它只适用于固定数量的部分。

这在SQL Server 2005上起作用,经过编辑以反映您的澄清:

select *
from Things t
where t.ThingID in (
    select top 10 ThingID
    from Things tt
    where tt.Section = t.Section and tt.ThingDate = @Date
    order by tt.DateEntered desc
    )
    and t.ThingDate = @Date
order by Section, DateEntered desc

如果您知道这些部分是什么,您可以执行以下操作:

select top 10 * from table where section=1
union
select top 10 * from table where section=2
union
select top 10 * from table where section=3

如果您使用的是SQL 2005,则可以执行以下操作

SELECT rs.Field1,rs.Field2 
    FROM (
        SELECT Field1,Field2, Rank() 
          over (Partition BY Section
                ORDER BY RankCriteria DESC ) AS Rank
        FROM table
        ) rs WHERE Rank <= 10
如果您的RankCriteria有联系,那么您可以返回超过10行,Matt的解决方案可能更适合您。

我这样做:

SELECT a.* FROM articles AS a
  LEFT JOIN articles AS a2 
    ON a.section = a2.section AND a.article_date <= a2.article_date
GROUP BY a.article_id
HAVING COUNT(*) <= 10;

更新:这个GROUPBY示例仅适用于MySQL和SQLite,因为这些数据库比标准SQL对GROUPBY的权限更大。大多数SQL实现都要求选择列表中不属于聚合表达式的所有列也在GROUP BY中。

我知道此线程有点旧,但我刚刚遇到了类似的问题,请从每个类别中选择最新的文章,这就是我提出的解决方案:

WITH [TopCategoryArticles] AS (
    SELECT 
        [ArticleID],
        ROW_NUMBER() OVER (
            PARTITION BY [ArticleCategoryID]
            ORDER BY [ArticleDate] DESC
        ) AS [Order]
    FROM [dbo].[Articles]
)
SELECT [Articles].* 
FROM 
    [TopCategoryArticles] LEFT JOIN 
    [dbo].[Articles] ON
        [TopCategoryArticles].[ArticleID] = [Articles].[ArticleID]
WHERE [TopCategoryArticles].[Order] = 1

这与Darrel的解决方案非常相似,但克服了可能返回比预期更多行的排名问题。

Q从每个组中查找前X条记录Oracle

SQL> select * from emp e 
  2  where e.empno in (select d.empno from emp d 
  3  where d.deptno=e.deptno and rownum<3)
  4  order by deptno
  5  ;

 EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
选择6行

在T-SQL中,我将执行以下操作:

WITH TOPTEN AS (
    SELECT *, ROW_NUMBER() 
    over (
        PARTITION BY [group_by_field] 
        order by [prioritise_field]
    ) AS RowNo 
    FROM [table_name]
)
SELECT * FROM TOPTEN WHERE RowNo <= 10

如果要生成按节分组的输出,则仅显示每个节的前n条记录,如下所示:

SECTION     SUBSECTION

deer        American Elk/Wapiti
deer        Chinese Water Deer
dog         Cocker Spaniel
dog         German Shephard
horse       Appaloosa
horse       Morgan
…那么下面的内容应该可以非常通用地用于所有SQL数据库。如果您想要前10名,只需将查询末尾的2改为10即可

select
    x1.section
    , x1.subsection
from example x1
where
    (
    select count(*)
    from example x2
    where x2.section = x1.section
    and x2.subsection <= x1.subsection
    ) <= 2
order by section, subsection;

如果我们使用SQL Server>=2005,那么我们只能通过一个选择来解决该任务:


您可以尝试这种方法。 此查询返回每个国家人口最多的10个城市

   SELECT city, country, population
   FROM
   (SELECT city, country, population, 
   @country_rank := IF(@current_country = country, @country_rank + 1, 1) AS country_rank,
   @current_country := country 
   FROM cities
   ORDER BY country, population DESC
   ) ranked
   WHERE country_rank <= 10;

尝试了以下方法,它也可以与领带一起使用

SELECT rs.Field1,rs.Field2 
FROM (
    SELECT Field1,Field2, ROW_NUMBER() 
      OVER (Partition BY Section
            ORDER BY RankCriteria DESC ) AS Rank
    FROM table
    ) rs WHERE Rank <= 10

虽然这个问题是关于SQLServer2005的,但大多数人都已经离开了,如果他们确实发现了这个问题,那么在其他情况下,什么可能是首选答案呢

挑选* 从t 交叉应用 选择前10名* 来自美国 其中u.t_id=t.t_id 由美国订购 U

此查询涉及2个表。OP的查询只涉及1个表,在这种情况下,基于窗口函数的解决方案可能更有效。

但这不适用于节为空的行。您需要说明tt.Section为null,t.Section为null或tt.Section=t.Section这将是最简单的方法。但如果您有150个类别,或者类别按天、周等变化,则这将是无效的。当然,但请引用OP:Sections是业务、本地和功能。如果你有三个静态类别,这是最好的方法。如果你真的想要前10名,把它改为RowNumber而不是Rank。这样就没有关系了。这是可行的,但请注意,如果没有索引,第一个键是RankCriteria,则查询计划器可能会将秩转换为完整表排序。在这种情况下,您可以选择不同的路段并交叉应用,以选择RankCriteria desc订购的前10名,从而获得更好的里程数。回答得很好!几乎完全满足了我的需要。我最终选择了稠密的等级,在编号上没有任何差距+1@Facbed这只是表上的一个别名。对于任何使用Sql Server的人来说,Mike L提到的RowNumber函数就是ROW_NUMBER。这样行吗?我很肯定您会发现a.somecolumn在选择列表中无效,因为它不包含在聚合函数中,也不包含在除article_id之外的项目中的每一列的group by子句中。您应该能够包含功能上依赖于group by中命名的列的其他列。功能上不相关的列是不明确的。但你是对的,这取决于RDBMS的实现。它在MySQL中工作,但在InterBase/Firebird中IIRC失败。如果某个区段的前11条记录都有相同的日期,这是否有效?它们的计数都是11,结果将是一个空集。不,如果它们都有相同的日期,你需要有一些打破关系的方法。例如,请参阅。@carlosgg,如果文章与节有多对多关系,则需要有一个交集表来将文章映射到它们的节。然后,您的查询必须连接到m2m关系的交叉表,并按项目id和节分组。这应该让你开始,但我不会在评论中写出整个解决方案。请对你的解决方案进行更多描述。REFERE:CTE的select查询是否可以包含where子句?@toha是的,尽管您在T-SQL中说这适用于任何实现行号的数据库

作用例如,我在SQLite中使用了这个解决方案,它也适用于PostgresSQL。我只需要使用order by[Prioritization_field]desc+1,我喜欢这个简单的解决方案,但是你能解释一下在order by子句中使用top 1如何处理返回0或1的case语句吗?top 1在这里处理TIES。使用TIES意味着,当ORDER BY=0时,SELECT将获取此记录,因为TOP 1和所有其他具有ORDER BY=0的记录,因为使用TIES,当我只需要每个部分的第一条记录时,这不起作用。它消除了所有具有1条以上记录的分区组。我试图替换@nils,因为只有三个部分值:鹿、狗和马。如果将查询更改为,但当我尝试运行查询时,它会消除所有内容,因为所有内容的计数都大于等于1。它没有为每个部分保留第1小节。你能试着运行@nils的查询吗?嗨,我确实从脚本中重新创建了这个小测试数据库,并使用它运行了查询,它在mysql中非常适合我。我改变了一个问题,不知道他为什么用这个问题是关于SQL Server,而不是Oracle。什么是别名为“m”的表?@Chalky它的拼写错误,应该是r。修好了,很有魅力。非常感谢。如果输入了一条领带怎么办?@Yiping未定义。任何争吵都可能获胜。这取决于许多情况,可能会有所不同。您可以通过添加更多列使订单更加具体,例如按r.DateEntered、r.ID排序,但这取决于您的特定任务。为什么要使用CTE先生?它能减少内存消耗吗?@toha因为CTE更简单,更容易理解,这是一个很好的答案!!它可以通过使用内部连接而不是左连接进行优化,因为如果没有相应的文章记录,就永远不会有TopCategoryArticles的记录。这些答案对你有用吗?我想我们永远也不会知道……已经过去12年了,我们不知道这些答案是否有效。例如,当我们有一个记录了一个国家9个相同人口的表时,这个解决方案不会通过测试用例它返回null,而不是按顺序返回所有9条可用记录。有任何解决此问题的建议吗?您好,在我在视图中添加聚合度量之前,查询对我来说很有效。从中选择rs.Field1、rs.Field2、rs.measure,从表rs中选择Field1、Field2、sumcastmeasure as INT overpartition by section as agg_measure、ROW_NUMBER OVER Partition by section ORDER by agg_measure DESC作为秩,其中秩
create table example ( id int, section varchar(25), subsection varchar(25) );

insert into example select 0, 'dog', 'Labrador Retriever';
insert into example select 1, 'deer', 'Whitetail';
insert into example select 2, 'horse', 'Morgan';
insert into example select 3, 'horse', 'Tarpan';
insert into example select 4, 'deer', 'Row';
insert into example select 5, 'horse', 'Appaloosa';
insert into example select 6, 'dog', 'German Shephard';
insert into example select 7, 'horse', 'Thoroughbred';
insert into example select 8, 'dog', 'Mutt';
insert into example select 9, 'horse', 'Welara Pony';
insert into example select 10, 'dog', 'Cocker Spaniel';
insert into example select 11, 'deer', 'American Elk/Wapiti';
insert into example select 12, 'horse', 'Shetland Pony';
insert into example select 13, 'deer', 'Chinese Water Deer';
insert into example select 14, 'deer', 'Fallow';
declare @t table (
    Id      int ,
    Section int,
    Moment  date
);

insert into @t values
(   1   ,   1   , '2014-01-01'),
(   2   ,   1   , '2014-01-02'),
(   3   ,   1   , '2014-01-03'),
(   4   ,   1   , '2014-01-04'),
(   5   ,   1   , '2014-01-05'),

(   6   ,   2   , '2014-02-06'),
(   7   ,   2   , '2014-02-07'),
(   8   ,   2   , '2014-02-08'),
(   9   ,   2   , '2014-02-09'),
(   10  ,   2   , '2014-02-10'),

(   11  ,   3   , '2014-03-11'),
(   12  ,   3   , '2014-03-12'),
(   13  ,   3   , '2014-03-13'),
(   14  ,   3   , '2014-03-14'),
(   15  ,   3   , '2014-03-15');


-- TWO earliest records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment) <= 2 
        then 0 
        else 1 
    end;


-- THREE earliest records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment) <= 3 
        then 0 
        else 1 
    end;


-- three LATEST records in each Section

select top 1 with ties
    Id, Section, Moment 
from
    @t
order by 
    case 
        when row_number() over(partition by Section order by Moment desc) <= 3 
        then 0 
        else 1 
    end;
   SELECT city, country, population
   FROM
   (SELECT city, country, population, 
   @country_rank := IF(@current_country = country, @country_rank + 1, 1) AS country_rank,
   @current_country := country 
   FROM cities
   ORDER BY country, population DESC
   ) ranked
   WHERE country_rank <= 10;
SELECT rs.Field1,rs.Field2 
FROM (
    SELECT Field1,Field2, ROW_NUMBER() 
      OVER (Partition BY Section
            ORDER BY RankCriteria DESC ) AS Rank
    FROM table
    ) rs WHERE Rank <= 10