2017-02-05 84 views
0

我正在使用会员列表和发票在我的俱乐部的php中建立一个网站。我已经安装我的数据库如下:我的查询应该如何设置?

家庭

ID 
Family name 
Adress 
etc. 

会员,并链接到家庭ID

ID 
Firstname 
Family_ID 

发票,并链接到任何家庭数据库或会员数据库

ID 
Amount 
payed 
Family_ID 
Member_ID 

有时候我想开发家庭,比如年度贡献。但有时候我想为会员本身发票来发票。

现在我想打一个概览页面,看起来有点像下面

Family name1 
     Contribution invoice1 
    Member1 
     Match invoice 1 
    member2 
     Match invoice 2 
Family name2 
     Contribution invoice2 
    Member1 
     Match invoice 3 
    member2 
     Match invoice 4 
etc.... 

我可以关闭过程做一个查询上家中所有的连接槽迭代他们。并且每行都为家庭成员查询和查询发票。然后再次查询每个成员的发票。但我认为应该有一个更复杂的查询来让他们在一个大的查询中。

我希望我的意思很清楚,你们可以帮助我。如果有问题,请告诉我。

回答

0

有点困难,没有演示数据。但我们假设以下方法:首先,我们构建临时inv_combined -table(作为from-部分中的选择),其将发票结合到家庭和成员,并分别分配contributionmember的类型。这个type稍后用于排序。然后,给出这个组合表,我们分别添加家庭和成员的详细信息。最后,我们按family.name, type, member.firstname排序,这样结果会为每个家庭首先列出所有缴费发票,然后列出所有会员发票。 在你的php代码中,你只需要通过列表并留意姓名,类型和成员名字的任何变化来开始新的部分。 希望它可以帮助(并希望它的作品):-)

select * from 
((select "Contribution" as type, if.* 
    from invoice if 
    where if.family_id is not null 
    ) 
    UNION 
    (select "Member" as type, im.* 
    from invoice im 
    where if.member_id is not null 
    ) 
) inv_combined left join family on inv_combined.family_id = family.id 
    left join member on inv_combined_member_id = member.id 
order by family.name, inv_combined.type, member.firstname 
+0

2个问题回: '如果*/IM *。' 1)你写的甲肝2倍。它有什么作用? 2)'inv_combined_member_id'是'inv_combined.member_id'? – DutchEcho

0

什么你将需要做的,我相信,是让你的主查询加盟成员和发票用某种内的子查询分隔符。现在,这看起来像是一个非常糟糕的查询,事实上它很复杂,但我在我的应用程序的多个位置工作。

$query = "SELECT Family.ID, Family.name, 
(SELECT GROUP_CONCAT(
    DISTINCT CONCAT_WS('|||', Member.ID, Member.Firstname 
    COALESCE((SELECT GROUP_CONCAT(
     DISTINCT CONCAT_WS('|', Contribution.ID, Contribution.Amount) 
    SEPARATOR '||') FROM Contribution WHERE Contribution.Member_ID = Member.ID AND Contribution.Family_ID = Family.ID),' '), ' ' 
) 
SEPARATOR '||||' 
) FROM Member WHERE Member.Family_ID = Family.ID) as Members 
FROM Family"; 


//Execute your query, get back $Families... 

foreach($Families as $k1=>$Family) { 
    $Family['Members'] = array_filter(explode("||||", trim($Family['Members']))); 

    foreach($Family['Members'] as $k2=>$Member) { 
     $Member = array_filter(explode("|||", trim($Member))); 
     $Member = [ 
      "ID" => $Member[0], 
      "Firstname" => $Member[1], 
      "Contributions" => array_filter(explode("||", trim($Member[2]))) 
     ]; 

     foreach($Member['Contributions'] as $k3=>$Contribution) { 
      $Contribution = array_filter(explode("|", trim($Contribution))); 

      $Contribution = [ 
       "ID" => $Contribution[0], 
       "Amount" => $Contribution[1] 
      ]; 
      $Member['Contributions'][$k3] = $Contribution; 
     } 
     $Family['Members'][$k2] = $Member; 
    } 
    $Families[$k1] = $Family; 
} 

我跑进与null值的一些问题时,我是建设它,我只是给你的梗概,但我基本上重写了整个事情的提问。您需要修改一些foreach数组,以便在最后处理该额外空间,删除任何空字符串(array_filter应该,但只是确定),并处理null值。

参考更多的援助(在那里我得到了这种类型的查询的帮助下):MySQL: Nested GROUP_CONCAT

+0

这看起来很复杂。明天我会看看它,所以我有更多时间去看看我不熟悉的所有额外代码;) – DutchEcho

+0

@DutchEcho这是你能够使用的东西吗?如果您有任何问题,请告诉我! – forrestmid

相关问题