动态检索多个表中的字段

时间:2012-07-20 06:25:37

标签: php mysql sql database-design

所以我有一个设计,人们被分组,这些组确定每个人保存的属性。

因此,如果稍后我决定要拥有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

p酒店业

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

xCustomers

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

如果查找两位先生,我们会得到满意的结果:

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))

如果我有其他子组,例如People>员工>管理者

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

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

我正在使用PHP和MySQL。

2 个答案:

答案 0 :(得分:0)

我修改了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

答案 1 :(得分:0)

如果你不介意有空列(你可以在php端处理它们),你可以在不使用动态查询的情况下获得所需的结果。这也可以让你丢弃分组表:dGROUPS和xGROUPS没有为此提供任何附加值 实体之间的关系已经由实际数据给出,它们只生成{{3 }}

这是用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)