使用基于子查询的值填充列

时间:2011-12-14 18:36:43

标签: mysql

我无法理解这个特殊问题,我希望你能提供帮助。我对MySQL并不是太糟糕,但肯定还是初学者。为了节省您的时间,我已将问题分解为最基本的元素。您需要的任何进一步的信息,只是让我知道它是什么,我会直接弹出它。

我有3个表:动物,所有者和地区

动物表包含有关每只动物的所有相关数据,以及引用所有者表的ID列的OwnerID列。 owner表类似,并且包含RegionID列(作为每个所有者地址的一部分),引用region表的ID列。 我希望在动物表上创建一个列,记录其所有者的RegionID。有没有我可以运行的UPDATE会复制这些数据?如果有人能通过这个过程跟我说话,我会非常感激。

我理想的最终结果是能够根据位置(从其所有者所在位置假定的位置)搜索动物。动物表中具有RegionID的列将允许我(在我的能力水平上)简单地执行此操作并作为进一步查询的一部分

#编辑

基本查询:

$base= "SELECT p.ID, p.Name, p.Prefix, CONCAT_WS(' ', p.Prefix, p.Name) AS ProfileName, 
        p.LocalRegNumber, p.GenderID, p.RegulatorID,
        p.ColourID, prm_colour.Name AS Colour, p.origColour,
        p.DiluteID, prm_dilute.Name AS Dilute,
        p.ModifierID, prm_modifier.Name AS Modifier,
        p.PatternID, prm_pattern.Name AS Pattern,
        p.DateofBirth, p.DateofDeath,
        EXTRACT(YEAR FROM p.DateofBirth) AS bYear, EXTRACT(YEAR FROM p.DateofDeath) AS dYear,
        p.SireReg, p.DamReg,
        p.OwnerID, p.BreederID,
        CONCAT_WS(' ', s.Prefix, s.Name) AS SireName,
        CONCAT_WS(' ', d.Prefix, d.Name) AS DamName,
        CONCAT_WS(' ', o.Firstname, o.Lastname) AS OwnerName,
        CONCAT_WS(' ', b.Firstname, b.Lastname) AS BreederName,
        prm_gender.Name AS Gender
                FROM profiles AS p
                    LEFT JOIN profiles AS s
                        ON p.SireReg = s.LocalRegNumber
                    LEFT JOIN profiles AS d
                        ON p.DamReg = d.LocalRegNumber
                            LEFT JOIN prm_colour
                                ON p.ColourID = prm_colour.ID
                            LEFT JOIN prm_dilute
                                ON p.DiluteID = prm_dilute.ID
                            LEFT JOIN prm_modifier
                                ON p.ModifierID = prm_modifier.ID
                            LEFT JOIN prm_pattern
                                ON p.PatternID = prm_pattern.ID
                    LEFT JOIN prm_gender
                                ON p.GenderID = prm_gender.ID
                            LEFT JOIN contacts AS o
                                ON p.OwnerID = o.ClientRef
                            LEFT JOIN contacts AS b
                                ON p.BreederID = b.ClientRef
                                 ";

然后我传递表单数据以获取应用了哪些过滤器(位置,年龄等)。例如,如果由所有者搜索:

$where = "WHERE (p.OwnerID = '$ownedby')";

然后构建查询:

$complete=$base.$where;
$q= mysql_query($complete);

2 个答案:

答案 0 :(得分:1)

你没有,你不应该这样做。 RegionId表中不需要额外的Animal列。对某个地区的动物进行seacrh,比如说“德克萨斯”,请使用:

SELECT a.*
FROM Animal AS a
WHERE OwnerId IN
      ( SELECT OwnerId
        FROM Owner
        WHERE RegionID IN
              ( SELECT RegionId
                FROM Region
                WHERE RegionArea = 'Texas'           --- example
              )
      )

或(通常表现更好):

SELECT a.*
FROM Animal AS a
  JOIN Owner AS o
    ON o.OwnerId = a.OwnerId
  JOIN Region AS r
    ON r.RegionId = o.RegionId
WHERE r.RegionArea = 'Texas'

您不想复制数据的原因与 normalization 良好的原因相同:

  

超过1NF(第一范式)的标准化目标由Codd说明如下:

     
      
  1. 从不受欢迎的插入,更新和删除依赖项中释放关系集合;
  2.   
  3. 随着新类型数据的引入,减少重建关系集合的需要,从而延长应用程序的使用寿命;
  4.   
  5. 使关系模型对用户更具信息性;
  6.   
  7. 使查询统计信息的关系集合中立,这些统计信息随着时间的推移可能会发生变化。
  8.   

如果所有者移动到另一个区域,请考虑您的方案中应该发生什么。除了他自己的RegionId之外,所有相关的动物行也必须更新。

你也可能(错误地)拥有与其所有者不同的RegionId动物。

答案 1 :(得分:1)

可以将这些信息复制到您的animal表格中,但是当您需要执行搜索时,仅使用JOIN会不会更好?

SELECT * FROM animal
  INNER JOIN owner ON animal.owner_id = owner.id
  INNER JOIN region ON owner.region_id = region.id
WHERE region.name = "myregion";

如果您需要经常访问此查询,可以考虑从此查询中创建VIEW