2013-08-19 19 views
6

Obecnie mam sql i php problemu gdzie Używam tego komunikatu, aby wszystko z usług, jak również związanych z nim tabel:MySQL oddzielonych przecinkami wartości

$db = $this->getDbo(); 
$query = $db->getQuery(true); 

// Select the required fields from the table. 
$query->select(
     $this->getState(
       'list.select', 'a.*' 
     ) 
); 

$query->from('`#__services_service` AS a'); 
$query->where("a.zone"); 

$query->select('zone.name AS zone, zone.description AS zone_description, zone.price AS zone_price, zone.interval_recommended AS interval_recommended'); 
$query->join('LEFT', '#__services_zones AS zone ON zone.id = a.zone'); 

$query->select('category.icon AS category'); 
$query->join('LEFT', '#__services_categories AS category ON category.id = a.category'); 

Ale w tabeli strefy łączę się, nie przecinek oddzielone wartości "1,2" i po utworzeniu tablicy asocjacyjnej, w której grupuję usługi do ich stref, pojedyncza usługa przechodzi do pojedynczej strefy, zamiast gdy wartość w tabeli wynosi "1,2", powinna być w obu strefy ... Mam wrażenie, że jest to z powodu 'zone.name AS zone', ponieważ wtedy zwraca tylko jedną nazwę i jeśli powiem 'zone AS zone' zwraca numery oddzielone przecinkami ...

Oto jak posortować tablicę:

foreach($this->items as $item){ 
if(!isset($zones[ $item->zone ])) 
$zone_items[ $item->zone] = array(); 
$zone_items[ $item->zone ][] = $item; 

    $zones[$item->zone] = array(
     'zone' => $item->zone, 
     'zone_interval' => $item->interval_recommended, 
     'zone_description' => $item->zone_description, 
     'zone_price' => $item->zone_price, 
     'items' => $zone_items[$item->zone] 
    ); 

} 

i wyświetlać je przez:

<?php foreach($zones as $zone): ?> 
    <div class="row-fluid zones-page"> 
     <div class="row-fluid zone-title-block"> 
      <div class="span4 zone-name"><h1><?php echo $zone['zone']; ?></h1></div> 
      <div class="span7 zone-description"> 
       <?php echo $zone['zone_description']; ?> 
       <?php if($zone['zone_interval'] == 1): ?> 
        <span class="interval pull-right">Interval Recommended</span> 
       <?php endif; ?> 
      </div> 
     </div> 

     <?php foreach($zone['items'] as $items) :?> 
     <div class="row-fluid zone-services-contain"> 
      <div class="span1"><div class="zone-icon"><?php //echo $items->category; ?></div></div> 
      <div class="span11 zone-services"> 
       <h4><?php echo $items->name; ?></h4> 
       <div><?php echo $items->description; ?></div> 
      </div> 
     </div> 
     <?php endforeach; ?> 

     <div class="row-fluid zone-amount"> 
      only <div><?php echo 'R' . $zone['zone_price']; ?></div> 
     </div> 
    </div> 
    <div class="bicycle-divider"> 
     <div class="bicycle-icon"></div> 
    </div> 
<?php endforeach; ?> 

Każda pomoc jest mile widziana.

tabela Services wygląda następująco:

enter image description here

a Zones Tabela:

enter image description here

+0

Jak wygląda stół? –

+0

który? .. usługi, strefy lub kategorie? –

+0

Tabela stref. –

Odpowiedz

8

To dlatego ludzie zwykle używać tabel linku do czynienia z wielu do wielu relacji lubię to. Jedna usługa może mieć wiele stref, jedna strefa może mieć wiele usług. Wyszukanie pola oddzielonego przecinkami i użycie go w połączeniu z inną tabelą jest dość trudne.

Masz dwie opcje, z których jedna polega na wykonaniu jej we właściwy sposób, a druga pozwala zachować bieżący model bazy danych. Sugeruję, aby zrobić to we właściwy sposób, ale aby odpowiedzieć na twoje pytanie, najpierw przejdę do drugiej opcji.

Po prostu oddzielaj zapytania. Wystarczy uzyskać pole oddzielone przecinkami w głównym zapytaniu, a następnie uruchomić drugą kwerendę, aby uzyskać nazwy stref:

SELECT * FROM zone WHERE id IN ($zoneIdsYouSelected) 

Teraz, jeśli pracujesz z listą, to prawdopodobnie nie jest bardzo wydajnych, ponieważ oznacza to, że Będziemy musieli wykonać jedno zapytanie dla listy, a kolejne dla każdego wiersza. Alternatywą byłoby, aby wszystkie strefy w tablicy, a następnie wybierz z tego przy użyciu PHP na podstawie $zoneIdsYouSelected. W ten sposób możesz uzyskać 2 zapytania zamiast tego, które planujesz osiągnąć, w przeciwieństwie do jednego zapytania w wierszu danych.

Właściwy sposób polega na utworzeniu tabeli linków, która po prostu zawiera dwa pola: zone_id i service_id. Jeśli następnie złożyć zapytanie tak, dostaniesz wszystkie nazwy w jednym „pole” w zestawie wyników:

SELECT s.id, s.name, s.description, s.price, s.category, s.ordering, 
     s.state, s.checked_out, s.checked_out_time, s.created_by, 
     GROUP_CONCAT(DISTINCT z.name ORDER BY z.name ASC SEPARATOR ', ') AS zones 
FROM  service s JOIN service_zone sz ON s.id = sz.service_id 
     JOIN zone z ON z.id = sz.zone_id 
GROUP BY s.id, s.name, s.description, s.price, s.category, s.ordering, 
     s.state, s.checked_out, s.checked_out_time, s.created_by 
ORDER BY s.id 

Prawdopodobnie będziesz musiał podkręcić tego zapytania trochę, ale mam nadzieję, że to jasne. Należy pamiętać, że GROUP_CONCAT nie jest obsługiwany przez wszystkie bazy danych, ale MySQL go posiada.

Ponownie, oba rozwiązania mogą działać dobrze i być wydajne, ale posiadanie pola oddzielonego przecinkami spowoduje więcej problemów, takich jak ten. Zdecydowanie zalecamy zmianę struktury bazy danych. Zapoznaj się z normalizacją bazy danych, jeśli nie wiesz, czym są tabele linków.

+0

Wow, dziękuję !, Nigdy nie myślałeś o łączeniu stołów ... Hej, zrób to we właściwy sposób !, jaki jest sens robienia czegoś i poznania jego zła? bardzo dziękuję .. źle próbuję to naprawdę szybko: D –

Powiązane problemy