2016-11-08 101 views
1

爲了從Oracle數據庫生成報告,我開始對一組數據進行研究。(嵌套?)使用MAX和WHERE子句選擇語句

的數據是在兩個表:

  1. 供應
  2. DEVICE

只有一列,這兩個表的鏈接:

  • SUPPLY .DE VICE_ID
  • DEVICE.ID

供應,有這些數據:(降價都不盡如人意。它應該顯示錶)

| DEVICE_ID  | COLOR_TYPE | SERIAL  | UNINSTALL_DATE  | 
|----------- |------------ |-------------- |--------------------- | 
| 1232   | 1    | CAP857496  | 08/11/2016,19:10:50 | 
| 5263   | 2    | CAP57421  | 07/11/2016,11:20:00 | 
| 758   | 3    | CBO753421869 | 07/11/2016,04:25:00 | 
| 758   | 4    | CC9876543  | 06/11/2016,11:40:00 | 
| 8575   | 4    | CVF75421  | 05/11/2016,23:59:00 | 
| 758   | 4    | CAP67543  | 30/09/2016,11:00:00 | 

設備,其中,有一些我已經選擇所有(或多或少)列,但每一行都是唯一的。

什麼,我需要實現的是: 每個SUPPLY.DEVICE_ID和SUPPLY.COLOR_TYPE,我需要最新ROW - > MAX(UNINSTALL_DATE)加入了與 或多或少所有的設備柱子

最後我應該有這樣的事情:

| ACCOUNT_CODE | MODEL  | DEVICE.SERIAL  | DEVICE_ID  | COLOR_TYPE | SUPPLY.SERIAL  | UNINSTALL_DATE  | 
|-------------- |------- |--------------- |----------- |------------ |--------------- |--------------------- | 
| BUSTO   | MS410  | LM753    | 1232   | 1    | CAP857496   | 08/11/2016,19:10:50 | 
| MACCHI  | MX310  | XC876    | 5263   | 2    | CAP57421   | 07/11/2016,11:20:00 | 
| ASL_COMO  | MX711  | AB123    | 758   | 3    | CBO753421869  | 07/11/2016,04:25:00 | 
| ASL_COMO  | MX711  | AB123    | 758   | 4    | CC9876543   | 06/11/2016,11:40:00 | 
| ASL_VARESE | X950  | DE8745   | 8575   | 4    | CVF75421   | 05/11/2016,23:59:00 | 

到目前爲止,使用嵌套選擇,如:

SELECT DEVICE_ID,COLOR_TYPE,SERIAL,UNINSTALL_DATE FROM 
(SELECT SELECT DEVICE_ID,COLOR_TYPE,SERIAL,UNINSTALL_DATE 
FROM SUPPLY WHERE DEVICE_ID = '123456' ORDER BY UNINSTALL_DATE DESC) 
WHERE ROWNUM <= 1 

我設法努力後獲得的UNISTALL_DATE列的最高值
MAX(UNISTALL_DATE) or HIGHEST(UNISTALL_DATE)

我也試過:

SELECT SUPPLY.DEVICE_ID, SUPPLY.COLOR_TYPE, .... 
FROM SUPPLY,DEVICE WHERE SUPPLY.DEVICE_ID = DEVICE.ID 

和它的作品,但給我的所有項目,基本上是兩個表的合併。 當我嘗試縮小選定的數據時,出現錯誤或空的結果。

,我開始懷疑,它是無法獲得這些數據,我開始在Excel中的數據和工作從那裏出口,但我希望在放棄之前有人能幫助我...

預先感謝您。

回答

0

for each SUPPLY.DEVICE_ID and SUPPLY.COLOR_TYPE, I need the most recent ROW -> MAX(UNINSTALL_DATE)

使用ROW_NUMBER功能以這樣的方式

SELECT s.*, 
     row_number() OVER (
      PARTITION BY DEVICE_ID, COLOR_TYPE 
      ORDER BY UNINSTALL_DATE DESC 
     ) As RN 
FROM SUPPLY s 

這個查詢標記與RN最近的行數= 1


JOINED with more or less all the columns in DEVICE.

剛剛加入上面查詢到設備表

SELECT d.*, 
     x.COLOR_TYPE, 
     x.SERIAL, 
     x.UNINSTALL_DATE 
FROM (
    SELECT s.*, 
      row_number() OVER (
       PARTITION BY DEVICE_ID, COLOR_TYPE 
       ORDER BY UNINSTALL_DATE DESC 
     ) As RN 
    FROM SUPPLY s 
) x 
JOIN DEVICE d 
ON d.DEVICE_ID = x.DEVICE_ID AND x.RN=1 
0

行 - 所以你可以分組device_id, color_typeselect max(uninstall_date)以及加入到其他表。但是您會錯過最近一行的serial值(對於每個組合device_id, color_type)。

有幾種方法可以解決這個問題。您嘗試使用rownum已接近,但問題是您需要在每個「組」(由device_id, color_type)內訂購併獲得每組的第一行。我確信有人會沿着這些線路發佈解決方案,使用row_number()rank()或可能是分析版本max(uninstall_date)

當你只需要從每個組的「頂」行,你可以使用keep (dense_rank first/last) - 這可能會略微高效 - 像這樣:

select device_id, color_type, 
     max(serial) keep (dense_rank last order by uninstall_date) as serial, 
     max(uninstall_date) as uninstall_date 
from  supply 
group by device_id, color_type 
; 

,然後加入到其他表。注意:dense_rank last將爲每個組選取最近(最多)日期的OR OR行。如果有關係,那不止是一行;那麼serial將成爲具有最近日期的那些行中的最大值(按字典順序)。你也可以選擇min,或者添加一些命令,以便選擇一個特定的命令(你沒有討論過這種可能性)。

0
SELECT 
     d.ACCOUNT_CODE, d.DNS_HOST_NAME,d.IP_ADDRESS,d.MODEL_NAME,d.OVERRIDE_SERIAL_NUMBER,d.SERIAL_NUMBER, 
     s.COLOR, s.SERIAL_NUMBER, s.UNINSTALL_TIME 
FROM (
     SELECT s.DEVICE_ID, s.LAST_LEVEL_READ, s.SERIAL_NUMBER,TRUNC(s.UNINSTALL_TIME), row_number() 
OVER (
     PARTITION BY DEVICE_ID, COLOR 
     ORDER BY UNINSTALL_TIME DESC 
    ) As RN 
FROM SUPPLY s 
WHERE s.UNINSTALL_TIME IS NOT NULL AND s.SERIAL_NUMBER IS NOT NULL 
     ) 

JOIN DEVICE d 
ON d.ID = s.DEVICE_ID AND s.RN=1; 

@krokodilko:非常感謝您的幫助。第一個查詢工作。修改它爲了刪除垃圾,把我需要的真正的列名(昨天晚上我沒有訪問數據庫),只獲取我需要的數據。

不幸的是,當我加入如你所說的兩個表,我得到錯誤:

ORA-00904: "S"."RN": invalid identifier 00904. 00000 - "%s: invalid identifier"

如果我刪除秒。在RN之前,ORA-00904移回s.DEVICE_ID。