根据一系列标准选择记录

时间:2016-10-13 12:59:26

标签: sql database oracle

我想运行一个查询,允许我根据特定条件从特定用户名中选择最佳记录。我有2列(col01,col02),这是我正在查看的标准。

•如果一条记录(以下示例中的用户名a)将两列都设为是,我希望该记录优先。

•如果一条记录的col01为yes,则接下来的第二级排名(下例中的用户名c)

•如果一条记录有col01,而另一条记录的col02为yes,则col01优先(下例中的用户名为d)。

•如果一条记录的col02为yes,另一条记录为no,则第二列的优先级排在第3位(下例中的用户名为g)。

•如果两个记录都相同,则不应返回任何记录,因为这些记录需要进一步调查(用户名b,e,f)

下面是示例示例和输出。如何使用sql查询完成?

+----------+-----+-------+-------+
| username | id  | col01 | col02 |
+----------+-----+-------+-------+
| a        | 1  | yes    | yes   |
| a        | 2  | yes    | no    |
| b        | 3  | no     | no    |
| b        | 4  | no     | no    |
| c        | 5  | yes    | no    |
| c        | 6  | no     | no    |
| d        | 7  | yes    | no    |
| d        | 8  | no     | yes   |
| e        | 9  | no     | yes   |
| e        | 10 | no     | yes   |
| f        | 11 | yes    | yes   |
| f        | 12 | yes    | yes   |
| g        | 13 | no     | no    |
| g        | 14 | no     | yes   |
+----------+----+--------+-------+

输出

+----------+-----+-------+------+
| username | id  | col01 | col02|
+----------+-----+-------+------+
| a        | 1  | yes    | yes  |
| c        | 5  | yes    | no   |
| d        | 7  | yes    | no   |
| g        | 14 | no     | yes  |
+----------+----+--------+------+

编辑:我被要求解释条件。基本上记录来自同一区域(用户名); col01是我们最近更新的信息,而col02更旧。这两个栏目对我们都很重要,所以如果两者都是肯定的话,那就更好了。更新的col01是更可靠的数据。在所有记录完全相同的情况下,我们必须更深入地了解数据。

3 个答案:

答案 0 :(得分:2)

使用分析函数,然后您不需要任何自连接:

<强>查询

SELECT username,
       id,
       col01,
       col02
FROM   (
  SELECT t.*,
         c.col2,
         MIN( t.col01 ) OVER ( PARTITION BY username ) AS mincol01,
         MAX( t.col01 ) OVER ( PARTITION BY username ) AS maxcol01,
         MIN( c.col02 ) OVER ( PARTITION BY username ) AS mincol02,
         MAX( c.col02 ) OVER ( PARTITION BY username ) AS maxcol02,
         ROW_NUMBER() OVER ( PARTITION BY username
                             ORDER BY t.col01 DESC, c.col02 DESC ) AS rn
  FROM   table_name t
         INNER JOIN
         col02_table c
         ON ( t.id = c.id )
)
WHERE  ( mincol01 < maxcol01 OR mincol02 < maxcol02 )
AND    rn = 1;

<强>输出

USERNAME ID COL01 COL02
-------- -- ----- -----
a         1 yes   yes
c         5 yes   no
d         7 yes   no
g        14 no    yes

答案 1 :(得分:1)

with
     inputs ( username, id, col01 , col02 ) as (
       select 'a',  1, 'yes', 'yes' from dual union all
       select 'a',  2, 'yes', 'no'  from dual union all
       select 'b',  3, 'no' , 'no'  from dual union all
       select 'b',  4, 'no' , 'no'  from dual union all
       select 'c',  5, 'yes', 'no'  from dual union all
       select 'c',  6, 'no' , 'no'  from dual union all
       select 'd',  7, 'yes', 'no'  from dual union all
       select 'd',  8, 'no' , 'yes' from dual union all
       select 'e',  9, 'no' , 'yes' from dual union all
       select 'e', 10, 'no' , 'yes' from dual union all
       select 'f', 11, 'yes', 'yes' from dual union all
       select 'f', 12, 'yes', 'yes' from dual union all
       select 'g', 13, 'no' , 'no'  from dual union all
       select 'g', 14, 'no' , 'yes' from dual
     )
-- Query begins here
select   username, 
         max(id) keep (dense_rank last order by col01, col02) as id, 
         max(col01)                                           as col01,
         max(col02) keep (dense_rank last order by col01)     as col02
from     inputs
group by username
having   min(col01) != max(col01) or min(col02) != max(col02)
;



USERNAME  ID COL COL
-------- --- --- ---
a          1 yes yes
c          5 yes no 
d          7 yes no 
g         14 no  yes

答案 2 :(得分:0)

使用多个外部自我联接,一个用于包含yes的记录,一个用于仅包含col01 = yes的记录,另一个用于仅包含col02 = yes的记录。然后添加谓词以仅选择其中id是该集合中第一个记录的id的记录(具有同名的行的id具有yes,具有相同名称的行的id仅具有col01 = {{1等等)
摆脱欺骗行,过滤掉有另一行的行(具有不同的id),其中username,col01和col02具有相同的值。

yes

如果Select distinct a.username, a.id, a.col01, a.col02 From table a left join table b -- <- this is rows with both cols = yes on b.username=a.username and b.col01='yes' and b.col02='yes' left join table c1 -- <- this is rows with col1 = yes on c1.username=a.username and c1.col01='yes' and c1.col02='no' left join table c2 -- <- this is rows with col2 = yes on c2.username=a.username and c2.col01='no' and c2.col02='yes' Where a.id = coalesce(b.id, c1.Id, c2.Id) and not exists -- <- This gets rid of f (select * from table where username = a.username and id != a.id and col01 = a.col01 and col02 = a.col02) 在另一个表中,那么在每个地方使用该表并需要col02,您需要在另一个表中添加另一个连接。

col02