如何查詢oracle 10中每個組的最後插入行
我有兩個關於使用者的表格,我想加入兩個表格並顯示每個使用者的最新評論
下面是表格
我想查詢每個使用者的最新評論(每個使用者 1 條評論)波紋管我寫的查詢但是如果日期和時間相同,它會返回每個使用者的多個評論
SELECT a.cust_id,b.remarks,b.contact_date,b.contact_time FROM customers a,(select * from customer_review where (cust_id,contact_time,contact_date) in (select cust_id, max(contact_time),max(contact_date) from customer_review group by cust_id) ) b WHERE a.cust_id=b.cust_id;
請為每個使用者查詢 1 條評論提供任何解決方案(注意:抱歉,如果有的話,我無法更改列詳細資訊) 實時連結Oracle Live
你想要做的是這樣的事情,使用 ROW_NUMBER() 和
PARTITION
cust_id 和ORDER
ingBY contact_time DESC
,這樣第一個將是最新的。這裡有一個小提琴- Oracle 具有微秒精度,因此您不太可能同時remarks
被同一客戶同時獲得。創建並填充客戶表:
CREATE TABLE customers ( cust_id INTEGER NOT NULL, cust_name VARCHAR (25) NOT NULL ); INSERT INTO customers VALUES (1234, 'John Doe'); INSERT INTO customers VALUES (1235, 'Ram'); INSERT INTO customers VALUES (1236, 'Rahim');
對 customer_review 執行相同的操作:
CREATE TABLE customer_review ( review_id VARCHAR (25) NOT NULL, cust_id INTEGER NOT NULL, remarks VARCHAR (250) NOT NULL, contact_date DATE NOT NULL, contact_time TIMESTAMP NOT NULL ); INSERT INTO customer_review VALUES ('NEW123', 1235, 'I am new user', TO_DATE('2019-10-27', 'yyyy-mm-dd'), TO_TIMESTAMP('2019-10-27 06:10:13.278', 'yyyy-mm-dd hh24:mi:ss:ms')); INSERT INTO customer_review VALUES ('CUST123', 1234, 'This is awesome product', TO_DATE('2019-10-26', 'yyyy-mm-dd'), TO_TIMESTAMP('2019-10-26 11:15:15.123', 'yyyy-mm-dd hh24:mi:ss:ms')); INSERT INTO customer_review VALUES ('CUST124', 1234, 'This is not good product. I have changed my mind now', TO_DATE('2019-10-27', 'yyyy-mm-dd'), TO_TIMESTAMP('2019-10-27 16:25:15.567', 'yyyy-mm-dd hh24:mi:ss:ms')); INSERT INTO customer_review VALUES ('CUST125', 1234, 'After upgrade, it is now working fine!', TO_DATE('2019-10-27', 'yyyy-mm-dd'), TO_TIMESTAMP('2019-10-27 19:52:56.345', 'yyyy-mm-dd hh24:mi:ss:ms'));
然後執行以下 SQL:
SELECT c.cust_name, t.cust_id, t.remarks FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY cust_id ASC, contact_time DESC) AS rn, * FROM customer_review ) t JOIN customers c ON t.cust_id = c.cust_id WHERE t.rn = 1;
結果:
CUST_ID REMARKS CUST_NAME 1234 After upgrade, it is now working fine! John Doe 1235 I am new user Ram
(編輯後 - 這些現在是正確答案 - John Doe 的評論應該是他的最新評論!Ram 只發表了一條評論,因此根據定義,它是最新的)。
幾句忠告。您的客戶表是複數形式,customer_review 是單數形式 - 選擇其中一個並堅持使用(您可以搜尋“SQL 樣式指南”並選擇您喜歡的一個。就個人而言,我推薦單數 - 表是一組事物的,因此是單一的。
下次發帖時,能否將您的表格定義包含為 DDL 文本 (
CREATE TABLE xxxx (field_1 type_1...);
) 並將您的數據包含為 DML 文本 (INSERT INTO xxxx VALUES (val_1, val2...);
)。以下是為什麼發布螢幕截圖不是解決 DBA.SE 問題的最佳方法的幾個原因。在我的個人資料中有幾篇關於如何提問的文章 - 你可能想看看?最後,我建議您使用整數
review_id
- 它使排序更容易 - 否則您可能會面臨不得不使用諸如SELECT CAST(SUBSTR('CUST1235', 5, LENGTH('CUST1235')) AS SMALLINT) AS no;
INTEGER
從review_id
欄位中提取。可以使用 Oracle ROWNUM偽列解決此問題,但這是非標準的,最好養成良好的習慣 - 如果您/您的公司決定這樣做,它將使您的應用程序更具可移植性。我希望這有幫助 - 如果它不符合您的要求,請告訴我,我們可以嘗試修改它。ps 歡迎來到論壇!:-)
編輯:
我終於讓 Oracle 小提琴在這里工作了——精確到微秒。
在重讀問題和我的答案時讓我印象深刻的另一點。您不需要聲明一個
contact_date
欄位 - 它可以很容易地從 contact_time 欄位派生出來。因此,數據(在這種情況下為日期)僅儲存在一個欄位和一個欄位中 - 這符合 RDBMS 最佳實踐。有兩種方法可以做到這一點
- 呼叫表時可以使用 TO_DATE 函式。您的表格現在看起來像這樣(註釋
contact_date
已被註釋掉。然後您只需TO_DATE(contact_time)
在您只想獲取日期時呼叫(範例在小提琴 - 表格中顯示customer_review_bis
)。CREATE TABLE customer_review_bis ( review_id VARCHAR (25) NOT NULL, cust_id INTEGER NOT NULL, remarks VARCHAR (250) NOT NULL, -- contact_date DATE NOT NULL, contact_time TIMESTAMP NOT NULL );
- 您還可以使用
GENERATED AS
(akaCOMPUTED BY
orCALCULATED
) 列。這些非常方便,一旦定義,您就可以有效保證日期將始終與contact_time
. 此功能曾經由TRIGGER
s 執行 - 確實值得學習這些功能。這裡column_name [datatype] [GENERATED ALWAYS] AS (expression) [VIRTUAL]
描述了語法(oracle-base 是一個超級站點)。您的表定義現在變為(也顯示在 fiddle - 中):customer_review_ter
CREATE TABLE customer_review_ter ( review_id VARCHAR (25) NOT NULL, cust_id INTEGER NOT NULL, remarks VARCHAR (250) NOT NULL, contact_time TIMESTAMP NOT NULL, contact_date DATE GENERATED ALWAYS AS (TO_DATE(contact_time)) VIRTUAL ); -- you just treat contact_date as a normal field when you call it, in -- exactly the same way as you did in your original example - table -- customer_review (first one) in the fiddle.
如果選擇
GENERATED AS
,則必須通過添加可更新的欄位來稍微修改INSERT
語句:INSERT INTO customer_review_ter (review_id, cust_id, remarks, contact_time) VALUES (.... data for specified fields ....);
最後,正如@EdStevens 所說,Oracle 10 是 EOL(生命終結)——你真的應該考慮升級!