2013-08-19 32 views
6

Şu anda ben hizmetlerinin yanı sıra ilişkili tablolardan şeyi almak için bu deyimi kullanın bir sql ve php sorunu: MySQL virgülle ayrılmış değerler

$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'); 

Ama katılmak bölge tablosunda

, virgül vardır '1,2' değerleri ayrılmış ve hizmetleri kendi bölgelerine göre gruplandırdığım bir ilişkisel dizi oluşturduktan sonra tekil bir hizmet tekil bir bölgeye gider, tablodaki değer '1,2' olduğunda, her ikisinde de olması gerekir. zonlar ... 'zone.name AS zone' nedeniyle bir his var çünkü o zaman sadece bir isim verir ve 'zone AS zone' derlerse virgülle ayrılmış sayıları döndürürsünüz ...

Burada dizi sıralamak nasıl:

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

} 

ve ben bunu göstermek: Herhangi bir yardım büyük takdir

<?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; ?> 

.

Services tablo gibi görünüyor:

enter image description here

Ve Zones Tablo: insanlar genellikle çok-çok ilişkileri ile başa çıkmak için bağlantı tabloları kullanmak neden

enter image description here

+0

Tablo neye benziyor? –

+0

hangisi? .. hizmetler, bölgeler veya kategoriler? –

+0

Bölge tablosu. –

cevap

8

budur bunun gibi. Bir servis birden fazla bölgeye sahip olabilir, bir bölge birden fazla servise sahip olabilir. Virgülle ayrılmış bir alanı sorgulamak ve başka bir tabloyla birleştirme içinde kullanmak oldukça zor.

İki seçeneğiniz var; bunlardan biri, doğru şekilde yapılmasını içerir ve bir tanesi, geçerli veritabanı modelinizi korumanıza olanak tanır. Bunu doğru şekilde yapmanızı şiddetle tavsiye ederim, ancak sorunuzu cevaplamak için önce diğer seçeneğe gideceğim.

Sorgularınızı ayırmanız yeterlidir. Sadece ana sorguda virgülle ayrılmış bir alan olsun, o zaman bölge adlarını almak için ikinci bir sorgu çalıştırmak: sizi demektir çünkü bir liste ile çalışıyorsanız, Şimdi

SELECT * FROM zone WHERE id IN ($zoneIdsYouSelected) 

, bu muhtemelen çok ölçülebilir değil Liste için bir sorgu çalıştırmalı ve her satır için bir başka. Bir alternatif, tüm bölgeleri bir diziye almak ve ardından $zoneIdsYouSelected'u temel alan PHP'yi kullanarak seçmektir. Bu şekilde, her bir veri hattı başına bir sorgu yerine, elde etmeyi planladığınız bir şey yerine 2 sorgu ile kaçabilirsiniz.

Doğru yol, yalnızca iki alan içeren bir bağlantı tablosu oluşturmayı içerir: zone_id ve service_id. Muhtemelen bu sorgu biraz esneteceksiniz

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 

, ama açıktır umut: o zaman böyle bir sorgu yaparsanız, sizin sonuç kümesindeki bir "alan" tüm isimleri alacak. GROUP_CONCAT'ın tüm veritabanları tarafından desteklenmediğini, ancak MySQL'in sahip olduğunu unutmayın.

Yine, her iki çözüm de düzgün çalışabilir ve performans gösterebilir, ancak virgülle ayrılmış bir alana sahip olmak tıpkı bunun gibi daha fazla sorun yaratacaktır. Veritabanı yapınızı değiştirmenizi şiddetle tavsiye ederim. Bağlantı tabloları fikrine aşina değilseniz, veritabanı normalleştirmeyi okuyun.

+0

Vay teşekkür ederim !, tabloları bağlama hakkında hiç düşünmemiştim ... Hey doğru yolu yap !, bir şey yapmanın ve yanlışını bilmenin anlamı nedir? çok teşekkür ederim .. çok çabuk teşebbüs ederim: D –

İlgili konular