MySQL中秩和密集秩的实现

时间:2015-06-09 07:28:53

标签: mysql sql-server oracle

您好我是MySql中的一名工程师,我想在MySql上实施排名和密集排名功能,以解决下面给出的问题陈述。

 我有一个名为Transaction_no | Register|Adult|child 的表,其中包含以下列:

+----------------+----------+-------+-------+
| transaction_no | register | adult | child |
+----------------+----------+-------+-------+
|           1234 |        A |     0 |     1 |
|           1234 |        A |     1 |     2 |
|           1234 |        A |     1 |     1 |
|           3456 |        B |     1 |     0 |
|           5678 |        B |     1 |     0 |
|           2468 |        C |     1 |     0 |
|           2468 |        C |     0 |     1 |
+----------------+----------+-------+-------+

输入数据如下:
INPUT

+----------------+----------+-------+-------+----+
| transaction_no | register | adult | child | rn | 
+----------------+----------+-------+-------+----+
|           1234 |        A |     0 |     1 |  1 |
|           1234 |        A |     1 |     2 |  2 |
|           1234 |        A |     1 |     1 |  3 |
|           3456 |        B |     1 |     0 |  1 |
|           5678 |        B |     1 |     0 |  1 |
|           2468 |        C |     1 |     0 |  1 |
|           2468 |        C |     0 |     1 |  2 |
+----------------+----------+-------+-------+----+

我的要求是使用mySQL添加另一列,即 rn ,它将使用Rank和密集等级的逻辑来生成以下中间输出

中间体

+----------------+----------+-------+-------+
| transaction_no | register | adult | child |
+----------------+----------+-------+-------+
|           1234 |        A |     0 |     1 |
|           3456 |        B |     1 |     0 |
|           5678 |        B |     1 |     0 |
|           2468 |        C |     1 |     0 |
+----------------+----------+-------+-------+

这里的分区是在交易号上完成的。

最终查询输出应包含 rn = 1的所有行,并且不应显示rn值。
OUTPUT

        amount  color     bullet size
Swiss    100    #0000FF       10
Spain    120    #FF0000       12
NL       70     #00FF00        7

Oracle文档供参考:GROUP_CONCAT

我还添加了SQL小提琴作为参考。OracleDocument

请帮我解决这个问题。

3 个答案:

答案 0 :(得分:0)

declare @t table (TransactionId int,register VARCHAR(1),Adult INT,Child INT )
insert into @t (TransactionId,register,Adult,Child)values (1234,'A',0,1),
(1234,'A',1,2),(1234,'A',1,1),(3456,'B',1,0),(5678,'B',1,0),(2468,'C',1,0),(2468,'C',0,1)
;with cte as (
select TransactionId,register,Adult,Child,ROW_NUMBER()OVER(PARTITION BY TransactionId,register  ORDER BY register ) RN from @t
)
Select TransactionId,register,Adult,Child from cte where RN = 1

答案 1 :(得分:0)

MySQL解决方案

SELECT transaction_no, register, adult, child
  FROM (
         SELECT
                ( CASE WHEN @prev_tno != transaction_no THEN @rn:=1 
                       ELSE @rn:=(@rn+1) END ) AS rn
              , @prev_tno:=transaction_no AS transaction_no
              , register, adult, child
           FROM instructor
              , (SELECT @rn:=0, @prev_tno:=NULL) AS row_nums
       ) src
 WHERE rn = 1
 ORDER BY register, transaction_no

注意:只能在显式请求中实现所需的排序,因此在查询中使用ORDER BY

答案 2 :(得分:0)

创建表TRANSACTION     (     Transaction_no int,     注册varchar2(2),     成人int,     孩子int     );

在TRANSACTION表中插入行。

中间输出的Sqlquery: -

从TRANSACTION选择TRANSACTION_NO,REGISTER,Adult,child,DENSE_RANK()over(按成人,子女的注册顺序)作为rnk;

最终输出的Sqlquery: -

选择TRANSACTION_NO,REGISTER,Adult,child from( 选择TRANSACTION_NO,REGISTER,Adult,child,DENSE_RANK()over(PARTITION BY TRANSACTION_NO ORDER BY Adult,child)作为来自TRANSACTION的rnk) 其中rnk = 1;

我在Oracle上尝试过。