2017-02-05 2 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 -part), который объединяет счета-фактуры с семьями и членами и присваивает тип contribution и member соответственно. Этот 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 вопросов назад: '. Если */им *. 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

Смежные вопросы