2011-11-15 54 views
1

我讀過聯接比子查詢更有效,我有一個查詢非常慢並且使用了大量的子查詢,因此我想改善它,但不知道如何。當查看同一個表中的另一條記錄時,將SQL子查詢轉換爲聯接Access 2010

我有以下表格:

People \\this table stores lists of individual people with the following fields 
( 
    ID, \\Primary Key 
    aacode Text, \\represents a individual house 
    PERSNO number, \\represent the number of the person in the house e.g. person number 1 
    HRP number, \\the PERSNO of the Housing Reference Person (HRP) the "main" person in the house 
    DVHsize number, \\the number of people in the house 
    R01 number, \\the persons relationship to the person who is PERSNO=1 
    R02 number, \\the persons relationship to the person who is PERSNO=2 
    R03 number, \\the persons relationship to the person who is PERSNO=3 
    AgeCat text, \\the age range of the person e.g. 30-44 
    xMarSta number, \\representing the marital satus of the person 
) 
Relatives \\this table stores the possible R01 numbers and their text equivalents 
(
    ID Primary Key, \\all possible R01 values 
    Relationship text, \\meaning of the corisponding R01 values 
) 
xMarSta \\this table store the possible xMarSta values and their text equivalents 
(
    ID Primary Key \\all possible xMarSta values 
    Marital text, \\meaning of corresponding R01 values 
) 

查詢是:

HsHld - 這個查詢的目標是爲每個房子(即每aacode)文本蜇描述的房子形式[Marital][AgeCat][Relationship][AgeCat][Relationship][AgeCat]等於是爲三人房子的輸出可能看起來像Married(30-44)Spouse(30-44)Child(1-4)

我知道我的電流HsHld代碼是可怕的,但它包含如下:

SELECT People.ID, People.aacode, People.PERSNO, 
     People.HRP, People.DVHsize, xMarSta.Marital, 
     [Marital] & " (" & [AgeCat] & ")" & [RAL2] & [RAge2] & 
     [RAL3] & [RAge3] & [RAL4] & [RAge4] & [RAL5] & [RAge5] & 
     [RAL6] & [RAge6] & [RAL7] & [RAge7] & [RAL8] & [RAge8] AS HsTyp, 
     (SELECT Fam2.R01 FROM People AS Fam2 WHERE Fam2.aacode = People.aacode 
     AND Fam2.PERSNO = 2) AS Rel2, 
     (SELECT Fam3.R01 FROM People AS Fam3 WHERE Fam3.aacode = People.aacode 
     AND Fam3.PERSNO = 3) AS Rel3, 
     Switch([Rel2] Is Null,Null,[Rel2]=-9,'DNA',[Rel2]=-8,'NoAns', 
       [Rel2]=1,'Spouse',[Rel2]=2,'Cohabitee',[Rel2]<7,'Child', 
       [Rel2]<10,'Parent',[Rel2]<15,'Sibling',[Rel2]=15,'Grandchild', 
       [Rel2]=16,'Grandparent',[Rel2]=17,'OtherRelative', 
       [Rel2]=20,'CivilPartner',True,'Other') AS RAL2, 
     Switch([Rel3] Is Null,Null,[Rel3]=-9,'DNA',[Rel3]=-8,'NoAns', 
       [Rel3]=1,'Spouse',[Rel3]=2,'Cohabitee',[Rel3]<7,'Child', 
       [Rel3]<10,'Parent',[Rel3]<15,'Sibling',[Rel3]=15,'Grandchild', 
       [Rel3]=16,'Grandparent',[Rel3]=17,'OtherRelative', 
       [Rel3]=20,'CivilPartner',True,'Other') AS RAL3, 
     (Select FAge2.AgeCat FROM People AS FAge2 
       WHERE FAge2.aacode = People.aacode 
       AND FAge2.PERSNO = 2 
     ) AS RAge2, 
     (Select FAge3.AgeCat FROM People AS FAge3 
       WHERE FAge3.aacode = People.aacode AND FAge3.PERSNO = 3 
     ) AS RAge3 
FROM Relatives 
RIGHT JOIN (xMarSta RIGHT JOIN People ON xMarSta.ID=People.xMarSta) 
      ON Relatives.ID=People.R01 
WHERE (((People.HRP)=[People.PERSNO])) 
ORDER BY People.aacode; 

有幾個關鍵的東西需要改變。

  1. 目前,我不能得到從相對字段加入到親屬 表工作,所以我使用所謂的RAL必有 有更好的方式開關功能。
  2. 爲簡單起見,我只包含了Rel2 & Rel3等,但在實際的代碼中,它上升到Rel13!所以表現的問題更加糟糕。
  3. 我想用連接替換這些子查詢,但是當子查詢 查看同一個表中的另一條記錄時,我不確定如何去 這一點。
  4. 我很出我的深度與此的,我知道一點點SQL但這個問題的複雜性 是太多我有限的知識
+0

啊,只是一個說明,你不應該打開復制的問題,編輯問題IDEIA是,如果你的第一個問題是不明確的,你可以編輯並提供更多信息。現在有3個重複的問題。考慮關閉其他的重複,並鏈接到這一個。 –

回答

0

首先,你有一個關係的情況,但你有的表結構是使用列來表示關係。這給你在桌子上的R01,R02,R03 ... R13列。不幸的是,你將無法顯着改變性能,因爲你的表結構是重複的非規範化而不是關係。這意味着你的查詢將需要所有這些重複的代碼,正如你所說的重複13次。這也意味着你的開關功能可以被一個連接所取代,但是也會重複13次。

現在回到您的查詢中,您的查詢中有多個子選擇,您需要在FROM子句的左連接上加入相關表並在選擇上使用新的相關別名。現在您將在下面的示例中看到,對於每個R01,R02字段,您將擁有Fam2,Fam3關係,並且您需要對您的案例執行此操作13次,並且對於每個您需要鏈接到親屬表的我確實叫Relat2,Relat3等)。現在,如果你可以改變你的數據庫結構的規範化結構,你真的可以簡化這個查詢,並使用更簡單的連接。

看看這一個可以幫助你理解這個過程:

SELECT People.ID, People.aacode, People.PERSNO, 
     People.HRP, People.DVHsize, xMarSta.Marital, 
     [Marital] & " (" & [People.AgeCat] & ")" & [RAL2] & [RAge2] & 
     [RAL3] & [RAge3] AS HsTyp, 
     Fam2.R01 AS Rel2, 
     Fam3.R01 AS Rel3, 
     Relat2.Relationship as RAL2, 
     Relat3.Relationship as RAL3, 
     Fam2.AgeCat AS RAge2, 
     Fam3.AgeCat AS RAge3 
FROM (((((People 
LEFT JOIN (People AS Fam2) ON (Fam2.aacode = People.aacode and Fam2.PERSNO = 2)) 
LEFT JOIN (Relatives as Relat2) on Relat2.Id = Fam2.R01) 
LEFT JOIN (People as Fam3) ON (Fam3.aacode = People.aacode AND Fam3.PERSNO = 3)) 
LEFT JOIN (Relatives as Relat3) on Relat3.Id = Fam3.R01) 
LEFT JOIN xMarSta ON xMarSta.ID=People.xMarSta) 
WHERE (People.HRP=[People.PERSNO]) 
ORDER BY People.aacode; 
+0

非常感謝,這完全解決了我的問題 – falcs

0

加入一個表,它的自我與一個別名完成

eg

SELECT * FROM [表1]加入[表1] T1上T1.SomeField = Table1.SomeOtherField

等。

Probaly不會有時間去修復它,但真正的問題出在哪裏你與R01,R02等去歸一化

你應該有一個其他表 RelationshipID PersonFrom PersonTo

你需要管理,雖然在Cr吃關係,這將意味着你的用戶界面和邏輯的變化。

+0

我試圖用這種方法替換RAge2字段,但得到錯誤消息沒有當前記錄,我使用的代碼是:(Select People。[AgeCat] FROM [People] INNER JOIN [People] AS P2 On People.aacode = P2.aacode WHERE P2.PERSNO = 2)AS RAge2, – falcs

+0

回答一個關於袖口的問題,看過你的問題,我現在對你的模式有點困惑。你可以發表一些示例行的People,Relations和XMarSta來說明記錄和表之間的隱含關係。我想我可以看到發生了什麼。哦,你可以在查詢中使用臨時表來處理,而不是重做模式。 –

相關問題