2012-12-27 43 views
0

我們在查詢後返回了cardID的列表,這些cardID屬於兩個表StudentPersonnel。那麼我怎樣才能加入那些cardIDStudentPersonnel,所以我可以根據cardID的返回一個表格顯示名稱StudentPersonnel從sql中的兩個單獨表中加入邏輯

人員表:

PERSONNELID NUMBER(9,0) 
PERSONNELNAME VARCHAR2(20)  
PERSONNELSURNAME VARCHAR2(20)  
PERSONNELJOB VARCHAR2(40)  
PERSONNELCARDID NUMBER(4,0) 

學生表:

STUDENTID NUMBER(9,0) 
STUDENTNAME VARCHAR2(20)  
STUDENTSURNAME VARCHAR2(20)  
STUDENTDEPT VARCHAR2(40)  
STUDENTFACULTY VARCHAR2(20)  
STUDENTCARDID NUMBER(4,0) 

CardId中

CARDID NUMBER(4,0) 
    USERTYPE VARCHAR2(20)  
    CHARGE NUMBER(3,2) 
    CREDIT NUMBER(4,2) 

PaymentDevice表:

ORDERNO NUMBER 
    PAYDEVIP NUMBER(8,0) 
    PAYDEVDATE DATE No 
    PAYDEVTIME VARCHAR2(8) 
    CHARGEDCARDID NUMBER(9,0) 
    MEALTYPE  VARCHAR2(10) 

我試圖返回第一個10人的姓名是吃食堂上27/12/2012

SELECT C.CARDID 
FROM CARD C, PAYMENTDEVICE P 
WHERE P.ORDERNO 
BETWEEN (SELECT MIN(ORDERNO) 
FROM PAYMENTDEVICE 
WHERE PAYDEVDATE='27/12/2012') AND (SELECT MIN(ORDERNO) 
FROM PAYMENTDEVICE 
WHERE PAYDEVDATE='27/12/2012')+10 AND C.CARDID=P.CHARGEDCARDID; 

我們orderNo沒有被複位,但每天不斷增加等等我們在當天發現了最小orderNo,並在此值上加10,以找到那個訂單號之間當天吃的前10個人。

那麼從該查詢返回:

CARDID 
    1005 
    1000 
    1002 
    1003 
    1009 
    2000 
    2001 
    1007 
    2002 
    1004 
    1006 

和那些其中的一些CardId中的(從1開始)是studentCardId,其中一些(始於2)PersonnelCardId。那麼,我該如何匹配和寫出相應的名字呢?

+0

...你可能應該有一個'個人'表,'id','name','surname'和'cardId'。然後使用'individualId','dept','faculty'將你現有的表格修改爲'Personnel',它具有'individualId','job'和'Student'。更乾淨。我的意思是,如果一個學生也是「人員」,會發生什麼?他們會得到第二張卡片嗎?你會期待他們在你的房源上出現兩次嗎?這將是'首選'重複? –

+0

我們不能根據他們的cardIds從不同的表中找到名字嗎? –

+0

也許你可以包括樣本起始數據和你想要的結果? –

回答

1
SELECT * 
FROM Personel p INNER JOIN Student s 
ON p.PersonnelCardId = s.StudentCardId 
INNER JOIN ReturnedQuery rq 
ON rq.CardId = p.PersonnelCardId 

更新:

SELECT p.PersonnelName, rq.CardId 
    FROM Personel p INNER JOIN ReturnedQuery rq 
    ON rq.CardId = p.PersonnelCardId 

    UNION 

    SELECT s.StudentName, rq.Cardid 
    FROM Student s INNER JOIN ReturnedQuery rq 
    ON s.StudentCardId = rq.Cardid 
+0

爲什麼你比較p.PersonnelCardId = s.StudentCardId?他們是不同的。 –

+0

如何更新一個? – urlreader

+0

我愛你,urlreader。 =) –

1

你原來的查詢實際上是非常脆弱的。我把它改寫像這樣(並添加所需的連接):

WITH First_Daily_Purchase as (SELECT chargedCardId, 
            MIN(payDevTime) as payDevTime, 
            MIN(orderNo) as orderNo 
           FROM PaymentDevice 
           WHERE payDevDate >= 
               TO_DATE('2012-12-27', 'YYYY-MM-DD') 
            AND payDevDate < 
               TO_DATE('2012-12-28', 'YYYY-MM-DD') 
           GROUP BY chargedCardId), 
    First_10_Daily_Purchasers as (SELECT chargedCardId 
            FROM (SELECT chargedCardId, 
               RANK() OVER(ORDER BY payDevTime, 
                   orderNo) as rank 
             FROM First_Daily_Purchase) a 
            WHERE a.rank < 11) 
SELECT a.chargedCardId, b.personnelName, b.personnelSurname 
FROM First_10_Daily_Purchasers a 
JOIN Personnel b 
ON b.personnelCardId = a.chargedCardId 
UNION ALL 
SELECT a.chargedCardId, b.studentName, b.studentSurname 
FROM First_10_Daily_Purchasers a 
JOIN Student b 
ON b.studentCardId = a.chargedCardId 

(有一個working SQL Fiddle - 一般子彈校對這花了好一會兒。)
這應該讓你誰做的第一個10人一次購買(不是第一次購買,這是你實際得到的)。這當然假設payDevTime實際上是以一種可排序的格式存儲的(如果它不是你有更大的問題比這個查詢工作不正確)。

也就是說,您的模式設計有許多令人不安的地方。

+0

非常感謝您的努力,Clockwork-Muse。 =)但是,時間格式與varchar數據類型不成問題。它與查詢順利進行。例如,我們能夠在特定的一天返回在'11:30:00'和'12:00:00'之間吃東西的學生。我們檢查了他們的數據,結果是真的。那麼在什麼地方可能存在時間問題,你能舉個例子嗎? –

+1

'payDevTime'可能是一種可排序的時間格式(例如,使用'09:00:00'而不是'9:00:00')。但是,通過組合日期和時間列可以更好地服務,因爲Oracle中的「日期」類型具有時間信息(這就是爲什麼我必須進行比較的原因,作爲範圍)。 –