2017-05-29 47 views
2

我目前在编写业务逻辑时遇到问题,无法从表中获取具有id和我已附加到其中的标志的行。SQL根据条件获取行

例如,

id: id seq num: flag: Date: 
A  1    N  .. 
A  2    N  .. 
A  3    N 
A  4    Y 
B  1    N 
B  2    Y 
B  3    N 
C  1    N 
C  2    N 

最终的结果我想实现的是: 对于每一个唯一的ID我只想取回一行与该行作为条件

如果该标志是“Y”,则返回该行。

否则返回最后一个“N”行。

另一个要注意的是,“Y”标志是不必总是最后

我一直试图让使用分区case条件像 OVER (PARTITION BY A."ID" ORDER BY A."Seq num")但至今没有运气。

- 编辑:

从表中,抽样结果将是:

id: id seq num: flag: date: 
A   4  Y  .. 
B   2  Y  .. 
C   2  N  .. 
+0

什么是你尝试的情况状况?你有没有试过把分区的结果放在公用表格表达式中,这样你就可以使用这种情况了? – Sander

+0

您能向我们展示您对该样本表的期望输出吗?我很难弄清楚“唯一ID”是指什么。 –

+0

@TimBiegeleisen我已添加结果 – Pyrons

回答

0

SELECT DISTINCT标识,标志 FROM yourTable

1

我的做法是采取两者的UNION查询。第一个查询只是简单地选择所有Yes记录,假设Yes只出现一次,每ID组。第二个查询只针对那些没有Yes任何地方的ID。对于这些记录,我们使用行号来选择最近的No记录。

WITH cte1 AS (
    SELECT id 
    FROM yourTable 
    GROUP BY id 
    HAVING SUM(CASE WHEN flag = 'Y' THEN 1 ELSE 0 END) = 0 
), 
cte2 AS (
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t1."id seq" DESC) rn 
    FROM yourTable t1 
    INNER JOIN cte1 t2 
     ON t1.id = t2.id 
) 
SELECT * 
FROM yourTable 
WHERE flag = 'Y' 
UNION ALL 
SELECT * 
FROM cte2 t2 
WHERE t2.rn = 1 
3

使用窗口子句是正确的想法。您应该由ID划分的结果(如你所做的),和秩序里面,这样Y标志行是第一位的,那么所有的N国旗行以日期降序排列,并挑头的每个ID:

SELECT id, id_seq_num, flag, date 
FROM (SELECT id, id_seq_num, flag, date, 
       ROW_NUMBER() OVER (PARTITION BY id 
            ORDER BY CASE flag WHEN 'Y' THEN 0 
                ELSE 1 
              END ASC, 
              date ASC) AS rk 
     FROM mytable) t 
WHERE rk = 1 
+1

这看起来不错,比我自己的查询更好+1 –

+0

@Mureinik抱歉后期问题,但如果'Y'每个ID出现多次,是否选择出现的第一个'Y'或按日期排序的最后一个'Y'?如果它确实选择了最后的'Y',那么如何修改才能选择第一个'Y'。谢谢 – Pyrons

+0

@Pyrons我编辑'order by'窗口子句,所以只选择第一个'Y'。 – Mureinik

1

这里有一种方法(用相当普通的SQL):

select t1.* 
from Table1 as t1 
where t1.id_seq_num = COALESCE( 
    (select max(id_seq_num) from Table1 as T2 where t1.id = t2.id and t2.flag = 'Y') , 
    (select max(id_seq_num) from Table1 as T3 where t1.id = t3.id and t3.flag = 'N')) 

可在小提琴这里:http://sqlfiddle.com/#!9/5f7f9/6

+0

嗨@Turophile,如果Table1碰巧是一个长查询,我不能使用视图,我怎么会写这个? – Pyrons

+0

您正在使用哪个数据库引擎? – Turophile

+0

现在好了。谢谢您的帮助 – Pyrons