在ORACLE中
Category表                
  CategoryId CategoryDESC     
  1           ...
  2           ...Product表 
  ProductId   CategoryId ProductDESC
  101         1          AAA
  102         1          BBB
  103         1          CCC
  104         2          DDD
  105         2          EEE
  106         2          FFF现要求一次性从product表中查出属于各个类别的前2条如:
  ProductId CategoryId ProductDESC
  101       1           AAA
  102       1           BBB
  104       2           DDD
  105       2           EEE请指点。
  
 

解决方案 »

  1.   

    Select * from  
    (select ProductId,CategoryId,ProductDESC,row_number() over (partition by CategoryId order by sal ProductId) rn 
     from Product)
     where rn<3
      

  2.   

    TO:qiaozhiwei(乔)
    看不懂,能给小弟解释一吗?
      

  3.   

    分析函数:
    转铁 
    这些都是分析函数,好像时8.0以后才有的
    row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序)
    rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)
    dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。
    相比之下row_number是没有重复值的
    lag(arg1,arg2,arg3):
    arg1是从其他行返回的表达式
    arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。
    arg3是在arg2表示的数目超出了分组的范围时返回的值。
    SQL> set pagesize 100;
    SQL> select rownum from emp;ROWNUM
    ----------
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14已选择14行。已用时间: 00: 00: 00.10
    SQL> select deptno,row_number() over(partition by deptno order by sal) from emp order by deptno;
    DEPTNO ROW_NUMBER()OVER(PARTITIONBYDEPTNOORDERBYSAL)
    ---------- ---------------------------------------------
    10 1
    2
    320 1
    2
    3
    4
    530 1
    2
    3
    4
    5
    6
    已选择14行。已用时间: 00: 00: 00.41
    SQL> select deptno,rank() over (partition by deptno order by sal) from emp order by deptno;DEPTNO RANK()OVER(PARTITIONBYDEPTNOORDERBYSAL)
    ---------- ---------------------------------------
    10 1
    2
    320 1
    2
    3
    4
    430 1
    2
    2
    4
    5
    6
    已选择14行。已用时间: 00: 00: 00.21
    SQL> select deptno,dense_rank() over(partition by deptno order by sal) from emp order by deptno;DEPTNO DENSE_RANK()OVER(PARTITIONBYDEPTNOORDERBYSAL)
    ---------- ---------------------------------------------
    10 1
    2
    320 1
    2
    3
    4
    430 1
    2
    2
    3
    4
    5
    已选择14行。已用时间: 00: 00: 00.20
    SQL> select deptno,ename,sal,lag(ename,1,null) over(partition by deptno order by ename) from emp ord
    er by deptno;DEPTNO ENAME SAL LAG(ENAME,
    ---------- ---------- ---------- ----------
    10 CLARK 2450
    KING 5000 CLARK
    MILLER 1300 KING20 ADAMS 1100
    FORD 3000 ADAMS
    JONES 2975 FORD
    SCOTT 3000 JONES
    SMITH 800 SCOTT30 ALLEN 1600
    BLAKE 2850 ALLEN
    JAMES 950 BLAKE
    MARTIN 1250 JAMES
    TURNER 1500 MARTIN
    WARD 1250 TURNER
    已选择14行。已用时间: 00: 00: 00.31
    SQL> select deptno,ename,sal,lag(ename,2,'example') over(partition by deptno order by ename) from em
    p order by deptno;DEPTNO ENAME SAL LAG(ENAME,
    ---------- ---------- ---------- ----------
    10 CLARK 2450 example
    KING 5000 example
    MILLER 1300 CLARK20 ADAMS 1100 example
    FORD 3000 example
    JONES 2975 ADAMS
    SCOTT 3000 FORD
    SMITH 800 JONES30 ALLEN 1600 example
    BLAKE 2850 example
    JAMES 950 ALLEN
    MARTIN 1250 BLAKE
    TURNER 1500 JAMES
    WARD 1250 MARTIN
    已选择14行。已用时间: 00: 00: 00.30这下应该没问题了吧?格式 
    analytic_function OVER 

     [PARTITION BY value_expr] 
     [    ORDER BY expr [ASC/DESC] [NULLS FIRST/NULLS LAST] 
                [ROWS/RANGE BETWEEN UNBOUNDED PRECEDING/ 
                                    CURRENT ROW/ 
                                    value_expr PRECEDING/FOLLOWING 
                                AND UNBOUNDED FOLLOWING/ 
                                    CURRENT ROW/ 
                                    value_expr PRECEDING/FOLLOWING 
                ] 
     ] 

    太复杂了,是吧?! 讲简单一点,分析函数是对查询结果的操作(多数为汇总类的函数) 
    其中:PARTITION BY子句用于分组(类似GROUP BY), 即在各个分组之内应用分析函数 
         ORDER BY子句用于在分组中排序 
         后面的一大串(即ROWS/RANGE BETWEEN...AND...)是对于每一行数据的分析范围 举几个例子: 1. 
    select empno, ename, deptno, sal, 
           sum(sal) over (partition by deptno order by ename) x 
    from scott.emp;  
    --注意PARTITION BY, ORDER BY 2. 
    select empno, ename, deptno, sal, 
           sum(sal) over (partition by deptno order by ename 
                          rows between unbounded preceding and current row) x 
    from scott.emp;  
    --注意ROWS BETWEEN unbounded preceding AND current row  
    --是指第一行至当前行的汇总 3. 
    select empno, ename, deptno, sal, 
           sum(sal) over (partition by deptno order by ename 
                          rows between current row and unbounded following) x 
    from scott.emp;  
    --注意ROWS BETWEEN current row AND unbounded following  
    --是指当前行到最后一行的汇总 4. 
    select empno, ename, deptno, sal, 
           sum(sal) over (partition by deptno order by ename 
                          rows between 1 preceding and current row) x 
    from scott.emp;  
    --注意ROWS BETWEEN 1 preceding AND current row 
    --是指当前行的上一行(rownum-1)到当前行的汇总 5. 
    select empno, ename, deptno, sal, 
           sum(sal) over (partition by deptno order by ename 
                          rows between 1 preceding and 2 following) x 
    from scott.emp;  
    --注意ROWS BETWEEN 1 preceding AND 1 following 
    --是指当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总 row_number得到的是分组中的行号 
    rank得到的是分组中的排名,如果排序值相同,rank()值相同 
    dense_rank与rank相似,只是不会跳号 例: 
    select empno,sal, 
           row_number() over(order by sal) x, 
           rank()       over(order by sal) y, 
           dense_rank() over(order by sal) z 
    from emp where deptno=30; EMPNO SAL      X   Y   Z 
    ----- -------- --- --- --- 
    7900      1500 1   1   1 
    7901      1500 2   1   1 
    7902      1600 3   3   2 
    7903      1700 4   4   3 
    7904      1700 5   4   3 
    7905      1700 6   4   3 
    7906      1800 7   7   4 
    7907      2000 8   8   5