Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 21

17
votes
answers
37 views
+10

Fetch the row which has the Max value for a column

Table:

UserId, Value, Date.

I want to get the UserId, Value for the max(Date) for each UserId. That is, the Value for each UserId that has the latest date. Is there a way to do this simply in SQL? (Preferably Oracle)

Update: Apologies for any ambiguity: I need to get ALL the UserIds. But for each UserId, only that row where that user has the latest date.

沙发
+20

i thing you shuold make this variant to previous query:

SELECT UserId, Value FROM Users U1 WHERE 
Date = ( SELECT MAX(Date)    FROM Users where UserId = U1.UserId)
板凳
+20

(T-SQL) First get all the users and their maxdate. Join with the table to find the corresponding values for the users on the maxdates.

create table users (userid int , value int , date datetime)
insert into users values (1, 1, '20010101')
insert into users values (1, 2, '20020101')
insert into users values (2, 1, '20010101')
insert into users values (2, 3, '20030101')

select T1.userid, T1.value, T1.date 
    from users T1,
    (select max(date) as maxdate, userid from users group by userid) T2    
    where T1.userid= T2.userid and T1.date = T2.maxdate

results:

userid      value       date                                    
----------- ----------- -------------------------- 
2           3           2003-01-01 00:00:00.000
1           2           2002-01-01 00:00:00.000
地板
+20

The answer here is Oracle only. Here's a bit more sophisticated answer in all SQL:

Who has the best overall homework result (maximum sum of homework points)?

SELECT FIRST, LAST, SUM(POINTS) AS TOTAL
FROM STUDENTS S, RESULTS R
WHERE S.SID = R.SID AND R.CAT = 'H'
GROUP BY S.SID, FIRST, LAST
HAVING SUM(POINTS) >= ALL (SELECT SUM (POINTS)
FROM RESULTS
WHERE CAT = 'H'
GROUP BY SID)

And a more difficult example, which need some explanation, for which I don't have time atm:

Give the book (ISBN and title) that is most popular in 2008, i.e., which is borrowed most often in 2008.

SELECT X.ISBN, X.title, X.loans
FROM (SELECT Book.ISBN, Book.title, count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title) X
HAVING loans >= ALL (SELECT count(Loan.dateTimeOut) AS loans
FROM CatalogEntry Book
LEFT JOIN BookOnShelf Copy
ON Book.bookId = Copy.bookId
LEFT JOIN (SELECT * FROM Loan WHERE YEAR(Loan.dateTimeOut) = 2008) Loan 
ON Copy.copyId = Loan.copyId
GROUP BY Book.title);

Hope this helps (anyone).. :)

Regards, Guus

4楼
+20

Assuming Date is unique for a given UserID, here's some TSQL:

SELECT 
    UserTest.UserID, UserTest.Value
FROM UserTest
INNER JOIN
(
    SELECT UserID, MAX(Date) MaxDate
    FROM UserTest
    GROUP BY UserID
) Dates
ON UserTest.UserID = Dates.UserID
AND UserTest.Date = Dates.MaxDate 
5楼
+20

I'm quite late to the party but the following hack will outperform both correlated subqueries and any analytics function but has one restriction: values must convert to strings. So it works for dates, numbers and other strings. The code does not look good but the execution profile is great.

select
    userid,
    to_number(substr(max(to_char(date,'yyyymmdd') || to_char(value)), 9)) as value,
    max(date) as date
from 
    users
group by
    userid

The reason why this code works so well is that it only needs to scan the table once. It does not require any indexes and most importantly it does not need to sort the table, which most analytics functions do. Indexes will help though if you need to filter the result for a single userid.

與大多數人相比,這是一個很好的執行計劃,但將所有這些技巧應用到更多的幾個領域將是乏味的,可能會對它起作用。但非常有趣 - 謝謝。見sqlfiddle.com/#!4/2749b5/23 - Used_By_Already 2014年8月7日7:11

你是對的它可能會變得乏味,這就是為什麼只有在查詢的性能需要它時才應該這樣做。ETL腳本通常就是這種情況。 - aLevelOfIndirection 2014年8月13日15:07

這非常好。使用LISTAGG做了類似的事情,但看起來很難看。postgres使用array_agg有更好的替代。看到我的答案:) - Bruno Calza 2014年11月13日13:26

6楼
+10
select userid, value, date
  from thetable t1 ,
       ( select t2.userid, max(t2.date) date2 
           from thetable t2 
          group by t2.userid ) t3
 where t3.userid t1.userid and
       t3.date2 = t1.date

IMHO this works. HTH

7楼
+10

I think this should work?

Select
T1.UserId,
(Select Top 1 T2.Value From Table T2 Where T2.UserId = T1.UserId Order By Date Desc) As 'Value'
From
Table T1
Group By
T1.UserId
Order By
T1.UserId
8楼
+10

First try I misread the question, following the top answer, here is a complete example with correct results:

CREATE TABLE table_name (id int, the_value varchar(2), the_date datetime);

INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'a','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(1 ,'b','2/2/2002');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'c','1/1/2000');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'d','3/3/2003');
INSERT INTO table_name (id,the_value,the_date) VALUES(2 ,'e','3/3/2003');

--

  select id, the_value
      from table_name u1
      where the_date = (select max(the_date)
                     from table_name u2
                     where u1.id = u2.id)

--

id          the_value
----------- ---------
2           d
2           e
1           b

(3 row(s) affected)
9楼
+10

This will also take care of duplicates (return one row for each user_id):

SELECT *
FROM (
  SELECT u.*, FIRST_VALUE(u.rowid) OVER(PARTITION BY u.user_id ORDER BY u.date DESC) AS last_rowid
  FROM users u
) u2
WHERE u2.rowid = u2.last_rowid
10楼
+10

Just tested this and it seems to work on a logging table

select ColumnNames, max(DateColumn) from log  group by ColumnNames order by 1 desc
11楼
+10

This should be as simple as:

SELECT UserId, Value
FROM Users u
WHERE Date = (SELECT MAX(Date) FROM Users WHERE UserID = u.UserID)

不正確,這不符合OP的需要。 - Woot4Moo 2013年3月18日14:16

12楼
+10

If you're using Postgres, you can use array_agg like

SELECT userid,MAX(adate),(array_agg(value ORDER BY adate DESC))[1] as value
FROM YOURTABLE
GROUP BY userid

I'm not familiar with Oracle. This is what I came up with

SELECT 
  userid,
  MAX(adate),
  SUBSTR(
    (LISTAGG(value, ',') WITHIN GROUP (ORDER BY adate DESC)),
    0,
    INSTR((LISTAGG(value, ',') WITHIN GROUP (ORDER BY adate DESC)), ',')-1
  ) as value 
FROM YOURTABLE
GROUP BY userid 

Both queries return the same results as the accepted answer. See SQLFiddles:

  1. Accepted answer
  2. My solution with Postgres
  3. My solution with Oracle
13楼
0

If (UserID, Date) is unique, i.e. no date appears twice for the same user then:

select TheTable.UserID, TheTable.Value
from TheTable inner join (select UserID, max([Date]) MaxDate
                          from TheTable
                          group by UserID) UserMaxDate
     on TheTable.UserID = UserMaxDate.UserID
        TheTable.[Date] = UserMaxDate.MaxDate;

我相信你也需要加入UserID - Tom H 09年9月23日14:49

你是對的。固定。 - 08年9月23日18:23

14楼
0
select   UserId,max(Date) over (partition by UserId) value from users;

這將返回所有行,而不是每個用戶一行。 - Jon Heller 2013年4月21日4:05

15楼
0

Solution for MySQL which doesn't have concepts of partition KEEP, DENSE_RANK.

select userid,
       my_date,
       ...
from
(
select @sno:= case when @pid<>userid then 0
                    else @sno+1
    end as serialnumber, 
    @pid:=userid,
       my_Date,
       ...
from   users order by userid, my_date
) a
where a.serialnumber=0

Reference: http://benincampus.blogspot.com/2013/08/select-rows-which-have-maxmin-value-in.html

這對“其他DB也不起作用”。這僅適用於MySQL,可能適用於SQL Server,因為它具有類似的變量概念。它肯定不適用於Oracle,Postgres,DB2,Derby,H2,HSQLDB,Vertica,Greenplum。另外,接受的答案是標準ANSI SQL(僅知道MySQL不支持) - a_horse_with_no_name 2013年8月30日18:55

馬,我想你是對的。我不了解其他數據庫或ANSI。我的解決方案能夠解決MySQL中的問題,它沒有對ANSI SQL的適當支持來以標準方式解決它。 - Ben Lin 2013年9月5日16:28

0
votes
answers
50 views
+10

PL/SQL:如何將行組合成一個字符串

1

在Oracle Database 12c上使用PL/SQL。PL/SQL:如何將行組合成一個字符串

我有這樣的一個表:

filename | priority       
---------- ----------- 
foo | 1   
bar | 2 
baz | 3  

我要創建這個字符串:FOO,1條,2,巴茲,3

什麼是做到這一點的最好方法是什麼?以前我用SQL Server和這工作:

DECLARE 
    @str varchar(100) 
SELECT @str = COALESCE(@str + ', ', '') + CONCAT(filename, ', ', priority) 
FROM table_name; 

但我想現在要做到這一點在Oracle中,我無法得到它的工作。我已經嘗試了一些方法,如:

DECLARE 
    str varchar(100) := coalesce(str || ', ', '') || CONCAT(filename, ', ', priority) 
FROM table_name; 

但我得到了這個錯誤,:「期待的下列之一,當‘

我也試着像LISTAGG’PLS-00103出現符號」 FROM :

listagg(filename|| ',' || priority, ',') within group (order by priority) as str 
from table_name; 

這給我的錯誤,「PLS-00103:出現符號‘在’在需要下列之一時」

我在做什麼錯?

+0

'DECLARE ... FROM TABLE_NAME' ??? –

+0

爲什麼你需要一個過程(和PL/SQL)代碼?你可以用普通的SQL來做到這一點。那麼 - 爲什麼你需要這樣做?可能有(很多)更好的方法來做你需要的東西;如果你能解釋爲什麼你需要它,我們可能會提供幫助。 – mathguy

+0

我正在修改用PL/SQL編寫的現有代碼以包含新功能。 – Murasaki

沙发
0
2

Oracle中的存儲過程由聲明部分和執行部分組成。您可以使用DECLARE部分來聲明變量,程序使用BEGINEND。使用SELECT INTO爲您的變量選擇一個值。

DECLARE 
    v_str varchar(10000); 
BEGIN 
    select 
    listagg(filename || ',' || priority, ',') within group (order by priority) 
    into v_str 
    from table_name; 

    ... 
END; 
+0

謝謝!我沒有意識到這個聲明不能和執行代碼在同一個塊中。 – Murasaki

0
votes
answers
35 views
+10

Oracle合併到(多個連接表)更新集(多個Where語句)返回無效的列規範

0

我是Oracle的新手。我正嘗試使用MERGE INTO方法更新SELECT DISTINCT語句中值的表值。我想根據USING表中的內容有條件地更新表的值。 的什麼,我基本上要一個快速的圖是Oracle合併到(多個連接表)更新集(多個Where語句)返回無效的列規範

MERGE 
INTO update_table ut 
USING 
(SELECT DISTINCT 
t1.column_1 
,t2.column_2 
FROM table_1 t1 
INNER JOIN table_2 t2 
ON t1.foreign_key = t2.primary_key) st 
ON (ut.pk = st.column_1) 
WHEN MATCH UPATE 
SET(ut.update_column = st.column_2 
    WHERE st.column_1 = 1 
    AND st.column_2 = 1 
    ,ut.update_column = st.column_2 
    WHERE st.column_1 = 2 
    AND st.column_2 = 2); 

然而,當我這樣做,我得到的,我用SET行了無效的列規格錯誤。我怎樣才能解決這個問題,以成功更新表格,最好是ANSI標準?

沙发
0
0

您可以在using子句本身的選定列表中添加where子句中添加的條件。喜歡這個。 (未經測試。你在where子句條件是不恰當的)

MERGE 
INTO update_table ut 
USING (SELECT DISTINCT 
       t1.column_1 , 
       CASE 
         WHEN t1.column_1 = 1 
           AND t2.column_2 = 1 
         THEN t2.column_1 
         WHEN t1.column_1 = 2 
           AND t2.column_2 = 2 
         THEN t2.column_2 
       END column_2 
     FROM 
       table_1 t1 
     INNER JOIN table_2 t2 ON t1.foreign_key = t2.primary_key 
     ) st 
ON (ut.pk = st.column_1) 
WHEN MATCHED THEN 
UPDATE SET ut.update_column = st.column_2 ; 
+0

好了,所以如果我的理解是正確的,這意味着我不能使用其中在這種情況下,語句。我需要擁有正確的數據集,而不是依賴update語句中的where子句。 – Jizzle21013

+0

@ Jizzle21013:如果你願意,你可以包含'ut.column_name = value'的where子句以及更新。但對於源表,最好將它限制在using子句本身中。 –

0
votes
answers
45 views
+10

裏面的CASE語句使用子查詢與生成序列ID

1

裏面我用子查詢CASE聲明,並在子查詢我們希望與自動序列值或計數器值一起一列。例如 CASE聲明裏面查詢就是這樣的,我們通過一列col1WHERE的條件下&得到輸出col2以及CNT裏面的CASE語句使用子查詢與生成序列ID

(CASE WHEN (SELECT COL2, ROWNUM AS CNT FROM TAB1 WHERE COL1 = COL1) THEN ....) 

每當任何值col1將匹配,則col2的輸出將被與CNT增量值產生沿。

CNT是這裏計數器的值等1,2,3,4,.....哪一個是更好的選擇或者使用計數器序列

+3

似乎查詢不作任何意義嗎? CASE的WHEN子句必須評估爲「true」或「false」,而不是數據表。 –

+0

在Oracle中,我只會使用'rownum'。 –

沙发
0
1

「哪一個是更好的選擇,或者使用計數器或序列。」

您是否總是希望CNT以1開頭?如果是這樣,你不想要一個序列。

有許多不同的方法可以爲CNT生成一個值。最簡單的就是使用rownum僞列:

SELECT COL1, rownum as CNT FROM TAB1 WHERE 

這是一個很好的解決方案,當你不小心給定行是否是1299999。如果你有一些特殊的要求,你可能要使用的解析函數像row_number()代替:

SELECT COL1, row_number() over (order by COL2) as CNT FROM TAB1 WHERE 
+1

請檢查一次編輯。這裏傳遞一個參數&獲得第二列與計數器。 –

+0

對不起,但我不明白你的意思。請提供一些示例輸入數據和您的預期輸出。 – APC

+0

但我沒有得到增量值時,我使用row_number()以及rownum兩者。我想增加值,如1,2,3,4 ... –

板凳
0
1

一般來說,「更好」取決於你想要做什麼。

有幾個可能的情形:

  1. 你集返回給調用一些代碼/用戶的結果。調用序列可能是不必要的開銷,並且不允許使用更復雜的行編號表達式。

    在這種情況下,我會使用哪個最適合的rownum和各種分析行編號函數,row_number()rank()dense_rank()

    由於您的查詢是如何構建的很可能是你應該使用這種方法的。

  2. 您正在將此數據插入表中。我更喜歡序列是一個標識列或在12c之前,在觸發器。這是因爲除了單個語句之外的其他代碼可能會執行插入操作,並且您希望確保更改表中數據的所有傳入數據都以相同方式處理。

    換句話說,不要在您的代碼中使用序列來執行此操作。

  3. 您正在生成一個唯一標識,您將向用戶顯示並插入表中。如果您有手動批准步驟,這種結構最有用。由於(2)中詳述的原因,您要使用序列來確保數據處理相同。

    另一種可能會導致鎖定的方法是執行插入操作,然後向用戶顯示未提交的數據。用戶然後必須提交或回滾適當的。

    如果您正在進行這些操作,您將失去未提交的序列值。這根本不重要,但由於某種原因它困擾了一些人。

0
votes
answers
38 views
+10

ORA-20010:DBMS_STATS內部錯誤fill_cstats:既DMIN/DMAX和n分鐘/ n最大是空的表SOA,列KEY,ssize 29892

0
ORA-20010: DBMS_STATS INTERNAL ERROR in fill_cstats : both dmin/dmax and nmin/nmax are null for table SOA, column KEY , ssize 29892 
ORA-06512: at "MOSTI", line 165 
ORA-06512: at line 1 

在生產中發生上述錯誤,可有人請解釋爲什麼會發生和解決方案?ORA-20010:DBMS_STATS內部錯誤fill_cstats:既DMIN/DMAX和n分鐘/ n最大是空的表SOA,列KEY,ssize 29892

+0

這是Oracle的內置DBSM_STATS收集日常內部錯誤。因此,您需要使用Oracle支持提出SR。如果您沒有支持合同,那麼您可能會運氣不好。你正在收集直方圖嗎?表分區了嗎? – APC

+0

表被分區。不收集直方圖。 –

+1

因此,您可能會遇到[已知的錯誤](https://support.oracle.com/knowledge/Oracle%20Database%20Products/2302863_1.html)。唉,只有當你有支持合同時纔有幫助。 – APC

沙发
0
1

這似乎是由於一個oracle內部的錯誤。

ORA-20010:DBMS_STATS內部錯誤Fill_cstat在分析 表(文檔ID 2247315.1)

收集表的統計信息時獲得以下錯誤:

EXEC DBMS_STATS.gather_table_stats (ownname =>'S',tabname =>'TEST', estimate_percent => 100,cascade => TRUE,granularity =>'ALL',degree => 2,no_invalidate => FALSE); *第1行的錯誤:ORA-20010:fill_cstats中的DBMS_STATS INTERNAL ERROR:對於表S.TEST,列 FIRST_NAME,ssize 430241 ORA-06512:在「SYS.DBMS_STATS」處,dmin/dmax和nmin/nmax都爲空,線34757 ORA-06512:在line 1

  1. 的BUG在12.2

  2. 解決方法的缺陷是刪除數據和重新收集統計信息

  3. 如果上述解決方法d OES不行,另一個潛在的解決方法是使用並行度爲1:

[email protected] DBMS_STATS.gather_table_stats(ownname => 'SCOTT', tabname => 'TEST', estimate_percent => 100, cascade => TRUE, degree => 1);

,但它符合甲骨文12.1

0
votes
answers
46 views
+10

在oracle表中選擇行所有者

0

我有一個名爲Table1的表,並且我有五個具有SELECT和INSERT權限的用戶,這些用戶中的每一個都將數據填充到表中。 如何顯示每一行是所有者?例如由user2插入的第1行,由user4插入的第2行等等?在oracle表中選擇行所有者

沙发
0
0

找出哪個用戶添加了現有行已經太晚了。要知道未來插入的行,該列添加到表:

alter table table1 add created_by varchar2(30) default user; 

另一種常用添加的列是:

alter table table1 add created_date date default sysdate; 
+0

請問這種填充誰插入記錄或誰創建該表的用戶的用戶? –

+0

@KaushikNayak誰插入了行 –

+0

謝謝..不知道爲什麼我困惑了一會兒。 –

0
votes
answers
44 views
+10

使用TO_CHAR在Oracle中進行數字格式化

0

在ORACLE存儲過程中格式化數字的正確方法。使用TO_CHAR在Oracle中進行數字格式化

我需要顯示2位小數的貨幣字段。 預期輸出如下:

  • 0> 0.00
  • 5> 5.00
  • 1253.6> 1253.60
  • 1253.689> 1253.69

下面爲我工作:

select to_char(9876.23 , 'fm999990.00') from dual; 

但這有硬c的問題編了一堆9。如果我給一個更大的數字,它會顯示爲「##############」

有沒有其他方法可以做到這一點?

+0

對於較大的數字,增加格式說明符中的9。 –

+0

我會很感激,如果下來的選民可以解釋爲什麼...... :( – PAVITRA

沙发
0
2

我需要2位小數,顯示貨幣字段。

確保您使用具有適合數據的比例和精度的數字數據類型,而不使用NUMBER而沒有比例和精度。如果你打算存儲美元/歐元/磅/等。那麼Gross World Product是的$ 100,000,000,000,000在2014年的訂單讓我們假設你是不是將要處理超過此[來源請求]那麼你的貨幣列可以是:

NUMBER(17,2) 

如果你得到一個價值大於此值,那麼您需要對您的數據執行完整性檢查,並考慮一個比世界總產品更大的數額是否合理。如果您要將這些值存儲爲例如日元或津巴布韋元,請適當調整比例。

你甚至可以在一個包中定義一個子類:

CREATE PACKAGE currencies_pkg IS 
    SUBTYPE currency_type IS NUMBER(17,2); 

    FUNCTION formatCurrency(
    amount IN CURRENCY_TYPE 
) RETURN VARCHAR2; 
END; 
/

您的代碼格式化,可以這樣:

CREATE PACKAGE BODY currencies_pkg IS 
    FUNCTION formatCurrency(
    amount IN CURRENCY_TYPE 
) RETURN VARCHAR2 
    IS 
    BEGIN 
    RETURN TO_CHAR(currency_value, 'FM999999999999990D00'); 
    END; 
END; 
/

然後,如果你引用的子類型的存儲過程/包,您將無法超過貨幣數據類型的最大大小,而不會引發異常。顯示值的格式模型只需要在一個地方定義,並且由於輸入限於貨幣子類型,所以格式化函數將永遠不會超過強加的比例/精度,並且不能輸出#

CREATE PROCEDURE your_procedure(
    in_value1 IN ACCOUNTS_TABLE.ACCOUNT_BALANCE%TYPE, 
    in_value2 IN ACCOUNTS_TABLE.ACCOUNT_BALANCE%TYPE 
) 
IS 
    v_value CURRENCIES_PKG.CURRENCY_TYPE; 
BEGIN 
    -- Do something 
    v_value := in_value1 + in_value2; 
    -- Output formatted value 
    DBMS_OUTPUT.PUT_LINE(CURRENCIES_PKG.formatCurrency(v_value)); 
END; 
/
+1

這是一個合理的論據對我來說。 – PAVITRA

板凳
0
1

爲什麼「硬編碼一堆9」是一個問題? (如果你打算使用TO_CHAR,你需要這麼做)

select to_char(9876.23 , 'fm9999999999999999999990D00') from dual; 

ps;你可能要考慮使用D而不是.(不是每個國家使用.作爲小數點分隔 - D是語言敏感,將使用相應的符號)

0
votes
answers
27 views
+10

如何用TABLE表達式「扁平」結構

1

我有一個VARRAYS TYPE想用TABLE表達式「扁平」結構。如何用TABLE表達式「扁平」結構

的示例數據

CREATE OR REPLACE TYPE ARIS.NUMBER_VARRAY_5 AS VARRAY (5) OF NUMBER NOT NULL; 


CREATE TABLE ARIS.TEST_2 
( 
    DATE_START DATE, 
    DATE_END DATE, 
    O3   ARIS.NUMBER_VARRAY_5, 
    CATEGORY NUMBER 
) 


SET DEFINE OFF; 
Insert into TEST_2 
    (DATE_START, DATE_END, O3, CATEGORY) 
Values 
    (TO_DATE('01/01/2005 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('01/05/2005 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), NUMBER_VARRAY_5(281.25,-9999,291.5,310.5,298.75), NULL); 
Insert into TEST_2 
    (DATE_START, DATE_END, O3, CATEGORY) 
Values 
    (TO_DATE('01/02/2005 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('01/06/2005 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), NUMBER_VARRAY_5(-9999,291.5,310.5,298.75,300.75), NULL); 
COMMIT; 

使用SQL語句

select O3.* from test_2 t, table(t.o3) O3 

我能得到的結果

COLUMN_VALUE 
281.25 
-9999 
291.5 
310.5 
298.75 
-9999 
291.5 
310.5 
298.75 
300.75 

的問題是我怎麼得到的結果類似

DATE_START DATE_END 03.VALUE1 03.VALUE2 03.VALUE3 03.VALUE4 03.VALUE5 
01/01/2005 01/05/2005    281.25 -9999  291.5 310.5  298.75 
01/02/2005 01/06/2005    -9999  291.5  310.5 298.75 300.75 
沙发
0
3

試試這個,

SELECT 
    * 
FROM 
    (
     select 
     t.Date_start, 
     t.Date_end, 
     row_number() OVER (PARTITION BY DATE_START, DATE_END 
     ORDER BY 
     ROWNUM) rn, 
     O3.* 
     from 
     test_2 t, 
     table(t.o3) O3 
    ) 
    PIVOT (MAX(column_value) FOR rn in 
    (
     1 as "03.VALUE1", 
     2 as "03.VALUE2", 
     3 as "03.VALUE3", 
     4 as "03.VALUE4", 
     5 as "03.VALUE5" 
    ) 
) ; 
0
votes
answers
43 views
+10

SQL:在更新

0

我不能發現我的請求,問題誤差內加盟。這裏是我的要求和2臺:SQL:在更新

UPDATE RESERVATION inner join client on reservation.numcl = client.numcl 
SET reservation.numcl2 = client.numcl2; 

錯誤:

=> [42000][971] ORA-00971: missing SET keyword 
  1. 表客戶 Client table

  2. 預訂客戶 reservation table

解決辦法:

UPDATE RESERVATION SET reservation.numcl2 = (select client.NUMCL2 
              from CLIENT 
              where client.NUMCL= RESERVATION.numcl); 
+0

你是在第一行之後突出顯示第一行還是錯過了';'? – Hans

+0

我並沒有真正明白你的意思,突出顯示了第一行,但內部連接在選擇實例中工作得很好。而且;應該在最後的權利? – Rotciv

+0

我認爲它不允許你「更新」一個連接。它正在尋找表名後面的'SET'關鍵字,當它執行一個簡單的'UPDATE'時,它通常會出現...... –

沙发
0
0

Oracle不支持在updatejoin(至少明確地)。你想要做什麼的等效是:

UPDATE RESERVATION r 
    SET numcl2 = (select client.NUMCL2 
        from CLIENT c 
        where c.NUMCL = r.numcl 
       ) 
    WHERE EXISTS (SELECT 1 FROM client c WHERE c.NUMCL = r.numcl); 

exists是很重要的,如果你想處理在沒有比賽的案件。

+0

好吧,我明白了!但在我的情況下,他們不能在預留數量不在客戶端,所以我不需要把它放在正確的?在存在選擇之後,'1'的用法是什麼? – Rotciv

+0

@Rotciv。 。 。如果你不需要檢查比賽,那麼你不需要。我只是指出Oracle中等效的語法。 「選擇」後面的內容並不重要; 「1」很容易打字。 –

0
votes
answers
29 views
+10

獲取嵌套表的引用的值

1

我試圖寫一個查詢來獲取IP地址,該地址是另一個嵌套表的引用的嵌套表的引用。獲取嵌套表的引用的值

create type t_pc as object (
     Nserie number(20), 
     adrIP VARCHAR(20), 
     cpu VARCHAR(20) 
    ); 

create type t_instatype as object(
    dateinst VARCHAR(20) , 
    refPC REF t_pc 
); 

create type t_installations as table of t_instatype ; 

create type t_logiciel as object (
    nomlogi VARCHAR(20) , 
    versionL VARCHAR(20) , 
    editeur VARCHAR(20), 
    installationsR t_installations 
); 

create type t_refLogiciel as object (
    refLogiciel ref t_logiciel 
); 

create type t_reflogiciels as table of t_reflogiciel ; 

create type t_adrType as object (
    rue VARCHAR(20) , 
    ville VARCHAR(20) 
); 

create type t_Depatement as object (
     codeDept number(20) , 
     nomDept varchar(20) , 
     budget varchar(20) , 
     refLogicielR t_reflogiciels , 
     AdrR t_adrType 
    ); 

下面是表:

create table Departement of t_Depatement 
    nested table refLogicielR store as rlogi ; 

create table Logiciel of t_logiciel 
    nested table installationsR store as insta ; 

create table PC of t_pc ; 

這裏的圖片顯示了我的數據

"MyTables "

我的查詢應檢索nomDept其中ADRIP是等於=「192.168表.2 .4;

預先感謝您

沙发
0
1

您可以瘦約Performing DML Operations on Collections (at: Unnesting Queries with Multilevel Collections) on Oracle Objects docs

Unnesting查詢,也可以使用多級收藏,無論可變數組和嵌套表。

這是查詢:

SELECT d.nomDept 
FROM Departement d, 
    table(d.refLogicielR) l, 
    table(l.refLogiciel.installationsR) i 
WHERE i.refPC.adrIP = '192.168.2.4' 

我想,這樣的回答,我贏得未來Oracle對象奇特的水平。

+1

謝謝曼 這就是我尋找的確切解決方案 –