2016-08-19 61 views
0

不同的I具有表A中所示:如何顯示列組的最大值。最大值應該從圖案

ID | L1 |L2 | Date   
-- |----- |---- | --------- 
1 | A | B | 2003-01-01 
---|------|-----|---------- 
2 | A | B | 2004-05-01 
---|------|-----|---------- 
3 | B | C | 2003-01-01 
---|------|-----|----------- 
4 | B | C | 9999-12-31 
---|------|-----|----------- 
5 | C | D | 1998-02-03 
---|------|-----|----------- 
6 | C | D | 2004-05-01 

正常情況是,當對一對字母(AB,BC,CD)是一個日期=「9999-12-31」 。因此,對於兩對字母(AB,CD),我錯過了日期'9999-12-31' ,我需要編寫一個查詢來查看這些字母和ID。

我寫的像(見對字母的最大日)查詢

select distinct L1, L2, max(date) from A GROUP BY 
L1, L2 
having max(date)<>'9999-12-31' 

此查詢顯示正確行,但我還需要看到的ID,這是我不能這樣做。有誰知道如何編寫查詢來查看ID也? ID始終是唯一的

謝謝!

+0

這還不清楚。所以你消除了B,C,因爲至少有一行在9999中有日期。這似乎很清楚。但是,對於A,B你是想要兩行還是隻有最高日期的行? C,D一樣。 – mathguy

+0

我想在查詢中顯示這對沒有日期='9999-12-31'的字母對的最高日期。所以在查詢的結果中,我需要有A,B和C,D兩個日期最高的日期。 –

回答

0

嘗試not exists

select a.* 
from a a 
where not exists (select 1 
        from a a2 
        where a2.l1 = a.l1 and a2.l2 = a.l2 and 
         a2.date = '9999-12-31' 
       ); 

這假定「日期」一欄被存儲爲一個字符串,或者你有日期格式設置,以便'9999-12-31'被正確地解釋(這是由您的樣品查詢建議)。否則,你可以使用:

a2.date = date '9999-12-31' 

編輯:

如果你想爲l1/l2`連擊不具有最大最高的日期,這很簡單:

select l1, l2, max(date) 
from a 
group by l1, l2 
having max(date) < date '9999-12-31'; 
+0

有一個問題是我的神經..你收到SO的錢嗎?你的工作是什麼?在這裏回答?我是這樣說的,因爲你一直在這裏......所以你在這裏工作? – stack

+0

@RGS你是他的答案的大追隨者?呵呵..當我提出一個關於數據庫的問題時,我只等**回答他的答案,並且我依靠他的答案作爲文檔。所以我想我是一個比你更大的追隨者:-)'..但你知道嗎?這是奇怪的。他爲什麼在這裏花費很多時間?他在這裏激活有什麼好處? – stack

+0

嗨戈登!感謝您的查詢,但它不符合任務的標準,因爲它顯示了這對L1,L2沒有日期= 9999-12-31的所有日期,但我需要查看這些日期的最高日期對沒有日期= 9999-12-31 ....你知道如何寫這樣的東西? –

1

如果您希望所有沒有日期等於9999-12-31的成對L1,L2的行,Gordon提供了一個解決方案。

如果您只查找沒有日期等於9999-12-31的對L1,L2,那麼這裏有一個解決方案,對於那些對,您只需要具有最新日期的行。

with 
    table_A (id, l1, l2, dt) as (
     select 1, 'A', 'B', date '2003-01-01' from dual union all 
     select 2, 'A', 'B', date '2004-05-01' from dual union all 
     select 3, 'B', 'C', date '2003-01-01' from dual union all 
     select 4, 'B', 'C', date '9999-12-31' from dual union all 
     select 5, 'C', 'D', date '1999-02-03' from dual union all 
     select 6, 'C', 'D', date '2004-05-01' from dual 
    ) 
select id, l1, l2, dt 
from (
     select id, l1, l2, dt, 
       row_number() over (partition by l1, l2 order by dt desc) rn 
     from table_A 
    ) 
where rn = 1 
and dt != date '9999-12-31' 
; 

    ID L1 L2 DT     
------ -- -- ------------------- 
    2 A B 2004-05-01 00:00:00 
    6 C D 2004-05-01 00:00:00 
+0

感謝您的回覆。但是我不能應用你的解決方案,因爲表A的值是硬編碼的(在CTE中)。我提供的表格只是我真實表格的一個「樣本」。我真正的桌子有超過5百萬行和4列的太多組合。這是不可能寫出像你這樣的查詢...你有任何其他的想法嗎?某種動態(非硬編碼)解決方案? –

+0

如果你有自己的表格,你根本不需要'table_A'。查詢從'select id,l1,l2,dt ...'開始 - 只要確保你的表被稱爲'table_A',或者如果它不是那麼只是在FROM條件中更改名稱。我創建的CTE是添加一些測試數據的非常常見的方式,但它不是解決方案的一部分。 – mathguy

+0

好的。那麼你知道我需要的解決方案可能是什麼樣子嗎? –

相關問題