【问题标题】:Dynamically retrieve fields across multiple tables跨多个表动态检索字段
【发布时间】:2012-07-20 20:16:47
【问题描述】:

所以我有一个设计,将人们分组,这些组决定每个人保存哪些属性。

因此,如果以后我决定要拥有 VIP 客户并记录他们的 VIP 号码,我可以创建一个名为“VIP 成员”的新组,并使用属性“VIP_Number”并将这些客户放在该组中。

因此,员工和其他客户没有与他们无关的字段。

现在,从给定人员的单独表中获取所有必需数据的最佳方法是什么?我需要一个支持以后添加的数据表的解决方案。

这是桌子的设计。

注意事项:

  • “d”前缀用于数据表
  • “x”前缀用于交叉引用表
  • “p”前缀用于属性
  • 我使用了不同长度的 ID 来帮助提高可读性
  • John Smith 是员工,因此也是人。
  • Anna Backhouse 是客户,因此也是人。
  • Mr Both 既是员工又是客户,因此也是个人。

dPeople

ID                   pFirst_Name          pLast_Name
----------------------------------------------------------
001                  John                 Smith
002                  Anna                 Backhouse
003                  Mr                   Both

dEmployees

ID                   pBadge_Code
----------------------------------------------------------
01                   MB2012
02                   JS2012

dCustomers

ID                   pPhone_Number
----------------------------------------------------------
01                   1800 backhouse
02                   1800 both

dGROUPS

ID                   pGroup_Name
----------------------------------------------------------
1                    People
2                    Employees
3                    Customers

xGROUPS

dGROUPS_ID_parent    dGROUPS_ID_child
----------------------------------------------------------
1                    1
1                    2
1                    3

xPeople

dPeople_ID           dGROUPS_ID
----------------------------------------------------------
001                  2
002                  3
003                  2
003                  3

xEmployees

dPeople_ID           dEmployees_ID
----------------------------------------------------------
001                  02
003                  01

xCustomers

dPeople_ID           dCustomers_ID
----------------------------------------------------------
002                  01
003                  02

查找 Mr Both 时的期望结果:

ID    pFirst_Name  pLast_Name  pBadge_Code  pPhone_Number
----------------------------------------------------------
003   Mr           Both        MB2012       1800 both

查找 John Smith 时的期望结果:

ID    pFirst_Name  pLast_Name  pBadge_Code  
----------------------------------------------------------
001   John         Smith       JS2012     

查找 Anna Backhouse 所需的结果:

ID    pFirst_Name  pLast_Name  pPhone_Number
----------------------------------------------------------
002   Anna         Backhouse   1800 backhouse

我可以得到他们正在使用的所有组的列表:

SELECT `dGROUPS`.`ID` AS `Group ID`, `dGROUPS`.`pGroup_Name` AS `Group Name` FROM `dGROUPS`, `xGROUPS` WHERE `xGROUPS`.`dGROUPS_ID_parent` = `dGROUPS`.`ID` AND (`xGROUPS`.`dGROUPS_ID_child` IN (SELECT `dGROUPS_ID` FROM `xPeople` WHERE dPeople_ID = 003))

当我有更多的子组(例如人员 > 员工 > 经理)时,这很有帮助

我想我需要运行此查询并使用它动态地形成另一个查询以获得所需的结果。我不介意使用两个查询,但最好使用一个。

也许有使用视图的解决方案?

我正在使用 PHP 和 MySQL。

【问题讨论】:

    标签: php mysql sql database-design


    【解决方案1】:

    我修改了 select 子句,星号选择所有列,甚至是后来添加到表中的新列。

    两位先生:

      --select dp.ID, dp.pFirst_Name, dp.pLast_Name, de.pBadge_Code, dc.pPhone_Number
        select dp.*, dp.*, dp.*, de.*, dc.*
        from dPeople dp join xCustomers xc
          on dp.id = xc.dPeople_ID
        join dCustomers dc
          on xc.dCustomers_ID = dc.ID
        join xEmployees xe
          on dp.id = xe.dPeople_ID
        join dEmployees de
          on  xe.dEmployees_ID = de.ID
    

    【讨论】:

    • 如果以后将新属性添加到表中或将人员添加到另一个组中,这将不起作用。我需要一个动态的解决方案。
    【解决方案2】:

    如果您不介意有空列(您可以在 php 端处理它们),您可以在不使用动态查询的情况下获得所需的结果。这也将允许您丢弃分组表:dGROUPS 和 xGROUPS 不提供任何附加值仅出于此目的实体之间的关系已经由实际数据给出,它们仅生成 Update anomalies .

    这是一个用 postgres 制作的示例(但你可以用 mysql 做同样的事情)。

    postgres=# with dPeople(ID, pFirst_Name, pLast_Name) as (
    postgres(#              values('001','John','Smith')
    postgres(#              union all
    postgres(#              values('002','Anna','Backhouse')
    postgres(#              union all
    postgres(#              values('003','Mr','Both')
    postgres(#      ), dEmployees(ID, pBadge_Code) as (
    postgres(#              values('01','MB2012')
    postgres(#              union all
    postgres(#              values('02','JS2012')
    postgres(#      ), dCustomers (ID, pPhone_Number) as (
    postgres(#              values('01','1800 backhouse')
    postgres(#              union all
    postgres(#              values('02','1800 both')
    postgres(#      ), xPeople (dPeople_ID, dGROUPS_ID) as (
    postgres(#              values('001','2')
    postgres(#              union all
    postgres(#              values('002','3')
    postgres(#              union all
    postgres(#              values('003','2')
    postgres(#              union all
    postgres(#              values('003','3')
    postgres(#      ), xEmployees (dPeople_ID, dEmployees_ID) as (
    postgres(#              values('001','02')
    postgres(#              union all
    postgres(#              values('003','01')
    postgres(#      ), xCustomers (dPeople_ID, dCustomers_ID) as (
    postgres(#              values('002','01')
    postgres(#              union all
    postgres(#              values('003','02')
    postgres(#      )
    postgres-# select *
    postgres-# from (
    postgres(#              select ID as dPeople_ID, pFirst_Name, pLast_Name
    postgres(#              from dPeople
    postgres(#      ) dPeople
    postgres-#      left outer join (
    postgres(#                      select dPeople_ID, dEmployees_ID, pBadge_Code
    postgres(#                      from xEmployees
    postgres(#                              join (
    postgres(#                                              select ID as dEmployees_ID, pBadge_Code
    postgres(#                                              from dEmployees
    postgres(#                                      ) as dEmployees using (dEmployees_ID)
    postgres(#              ) as Employees using (dPeople_ID)
    postgres-#      left outer join (
    postgres(#                      select dPeople_ID, dCustomers_ID,  pPhone_Number
    postgres(#                      from xCustomers
    postgres(#                              join (
    postgres(#                                              select ID as dCustomers_ID, pPhone_Number
    postgres(#                                              from dCustomers
    postgres(#                                      ) as Customers using (dCustomers_ID)
    postgres(#              ) as Customers using (dPeople_ID)
    postgres-# ;
     dpeople_id | pfirst_name | plast_name | demployees_id | pbadge_code | dcustomers_id | pphone_number
    ------------+-------------+------------+---------------+-------------+---------------+----------------
     001        | John        | Smith      | 02            | JS2012      |               |
     002        | Anna        | Backhouse  |               |             | 01            | 1800 backhouse
     003        | Mr          | Both       | 01            | MB2012      | 02            | 1800 both
    (3 rows)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      相关资源
      最近更新 更多