查看同一个表 Access 2010 中的另一条记录时,将 SQL 子查询转换为联接 [英] Convert a SQL subquery into a join when looking at another record in the same table Access 2010

查看:12
本文介绍了查看同一个表 Access 2010 中的另一条记录时,将 SQL 子查询转换为联接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读到联接比子查询更有效,我有一个查询非常慢并且使用大量子查询,因此我想改进它但不知道如何改进.

I have read that Joins are more efficient than subqueries, I have a query that is extremely slow and uses lots of subqueries, therefore I would like to improve it but do not know how.

我有以下表格:

 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 - the goal of this query is to produce for each house (i.e. each aacode) a text sting describing the house in the form [Marital][AgeCat][Relationship][AgeCat][Relationship][AgeCat] etc. So an output for a three person house might look like Married(30-44)Spouse(30-44)Child(1-4)

我知道我当前的 HsHld 代码很糟糕,但它包含在下面:

I know my current code for HsHld is terrible, but it is included below:

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;

有几个关键的事情需要改变.

There are several key things that need to change.

  1. 目前我无法从 Rel 字段加入到亲属表工作,所以我必须使用一个名为 RAL 的 Switch 函数成为更好的方法.
  2. 为简单起见,我只包含了 Rel2 &Rel3 等,但在实际代码中它上升到 Rel13!所以性能问题就更严重了.
  3. 我想用连接替换这些子查询,但是作为子查询查看同一张表中的另一条记录我不确定如何去关于这个.
  4. 我对此非常了解,我知道一点 SQL,但是这个问题的复杂性对于我有限的知识来说太过分了

推荐答案

首先你有一个关系情况,但是你的表结构是使用列来表示关系.这为您提供了表格上的 R01、R02、R03 ... R13 列.不幸的是,您将无法显着改变性能,因为您的表结构是重复的非规范化而不是关系.这意味着您的查询将需要所有这些重复代码,正如您提到的重复 13 次.这也意味着你的 switch 函数可以被 join 替换,但又会重复 13 次.

The very first thing is that you have a relational situation but the table structure you have is using columns to represent relationships. This gives you the R01, R02, R03 ... R13 columns on your table. Unfortunately you will not be able to change performance dramatically because your table structure is repetitive denormalized instead of relational. This means that your query will need all this repetitive code, as you mentioned repeating 13 times. That also means that your switch function can be replaced by a join but again will be repeated 13 times.

好的,现在回到您的查询,您的查询有多个子选择,您需要在 FROM 子句的左连接上连接相关表,并在您的选择上使用新的相关别名.现在您将在下面的示例中看到,对于每个 R01、R02 字段,您将有一个 Fam2、Fam3 关系,您需要在您的案例中执行此操作 13 次,并且对于每个您需要链接到亲属表(如我确实调用了 Relat2、Relat3 等).现在,如果您可以将数据库结构更改为规范化结构,您就可以真正简化此查询并使用更简单的连接.

Right, now back to your query, you have multiple sub-selects on your query and you need to join the related tables on a left join on the FROM clause and use the new related alias on your select. now you will see on the example below that for each R01, R02 field you will have a Fam2, Fam3 relation and you will need to do this 13 times on your case, and for each one you need to link to the relatives table (as i did called Relat2, Relat3, etc). Now if you can change your database structure for a normalized structure, you could really simplify this query and use much simpler joins.

看看这个是否能帮助你理解这个过程:

See if this one helps you understand the process:

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; 

这篇关于查看同一个表 Access 2010 中的另一条记录时,将 SQL 子查询转换为联接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆