2016-04-25 12 views
2

私の問題:私は時間をかけて配られた複数の店舗から数えて(注文する)必要があります。もちろんOrdercreatedAtフィールドを含み、双方向ManyToOneShopの関係にあります。Doctrineは数時間に渡って配られたエンティティを取得します

DQLで行うことができますか、またはプレーンSQLを使用する必要がありますか?注文を受け取り、ループで並べ替える必要がありますか?

ベストプラクティスは何ですか? Excelで期待される結果は次のとおりです。

enter image description here

私の現在のソリューション:

リポジトリ:

public function findSortedToday() 
{ 
    $orders = $this->createQueryBuilder('o') 
     ->select('HOUR(o.createdAt) AS oCreated') 
     ->addSelect('SUM(od.dishPrice) AS odSum') 
     ->addSelect('(os.name) AS oShop') 
     ->innerJoin('o.shop', 'os') 
     ->innerJoin('o.dishes', 'od') 
     ->groupBy('oCreated') 
     ->addGroupBy('os') 
     ->getQuery() 
     ->getResult(); 
    return $orders; 
} 

コントローラー:

... 
    $ordersByHourArray = $this->getDoctrine()->getRepository("TerminalBundle:Order")->findSortedToday();   
    foreach ($ordersByHourArray as $data) 
    { 
     $resByHourArray[$data["oShop"]][$data["oCreated"]] = $data["odSum"]*1; 
    } 
    foreach ($resByHourArray as $shop => $data) 
    { 
     for ($h = 0; $h <= 23; $h++){ 
      if (!array_key_exists($h, $data)) $resByHourArray[$shop][$h] = 0; 
     } 
     ksort($resByHourArray[$shop]); 
    } 
    ... 

答えて

0

あなたは注文数が水平方向に分割したい場合、すなわち、行方向。

select s.id shop_id, 
     concat(case when date_format(now(),'%H') > 12 
     then concat(date_format(now(),'%H') - 12,' PM') 
     else concat(date_format(now(),'%H'),' AM') end 
     ,' - ',case when date_format(now(),'%H') + 1 > 12 
     then concat(date_format(now(),'%H') + 1 - 12,' PM') 
     else concat(date_format(now(),'%H') + 1,' AM') end) window, 
     count(*) orders 
from orders o 
left join shops s 
on s.id = o.shop_id 
group by s.id, window; 

注文を垂直に分割する場合、つまり列単位で分割する場合は、

select s.shop_id, 
     count(distinct case when hour(now()) = 0 then o.order_id else 0 end) 'midnight - 1 AM', 
     count(distinct case when hour(now()) = 1 then o.order_id else 0 end) '1 - 2 AM',  
     count(distinct case when hour(now()) = 2 then o.order_id else 0 end) '2 - 3 AM',  
     count(distinct case when hour(now()) = 3 then o.order_id else 0 end) '3 - 4 AM',  
     count(distinct case when hour(now()) = 4 then o.order_id else 0 end) '4 - 5 AM',  
     count(distinct case when hour(now()) = 5 then o.order_id else 0 end) '5 - 6 AM',  
     count(distinct case when hour(now()) = 6 then o.order_id else 0 end) '6 - 7 AM',  
     count(distinct case when hour(now()) = 7 then o.order_id else 0 end) '7 - 8 AM',  
     count(distinct case when hour(now()) = 8 then o.order_id else 0 end) '8 - 9 AM',  
     count(distinct case when hour(now()) = 9 then o.order_id else 0 end) '9 - 10 AM',  
     count(distinct case when hour(now()) = 10 then o.order_id else 0 end) '10 - 11 AM',  
     count(distinct case when hour(now()) = 11 then o.order_id else 0 end) '11 - noon',  
     count(distinct case when hour(now()) = 12 then o.order_id else 0 end) 'noon - 1 PM',  
     count(distinct case when hour(now()) = 13 then o.order_id else 0 end) '1 - 2 PM',  
     count(distinct case when hour(now()) = 14 then o.order_id else 0 end) '2 - 3 PM',  
     count(distinct case when hour(now()) = 15 then o.order_id else 0 end) '3 - 4 PM',  
     count(distinct case when hour(now()) = 16 then o.order_id else 0 end) '4 - 5 PM',  
     count(distinct case when hour(now()) = 17 then o.order_id else 0 end) '5 - 6 PM',  
     count(distinct case when hour(now()) = 18 then o.order_id else 0 end) '6 - 7 PM',  
     count(distinct case when hour(now()) = 19 then o.order_id else 0 end) '7 - 8 PM',  
     count(distinct case when hour(now()) = 20 then o.order_id else 0 end) '8 - 9 PM',  
     count(distinct case when hour(now()) = 21 then o.order_id else 0 end) '9 - 10 PM',  
     count(distinct case when hour(now()) = 22 then o.order_id else 0 end) '10 - 11 PM',  
     count(distinct case when hour(now()) = 23 then o.order_id else 0 end) '11 PM - midnight'  
from shops s inner join orders o on o.shop_id = s.shop_id; 
0

あなたは、あなたのニーズに合わせて、SELECT句(単純化の例)で、グループにキーを作成することができます:周りを再生するには

SELECT 
    CONCAT(MONTH(date), '-', DAY(date), '-', HOUR(date)) AS daytime, 
    shop, 
    COUNT(id) as cnt 
FROM orders 
GROUP BY daytime, shop; 

http://sqlfiddle.com/#!9/67285/2


現在、あなたは1日のみの集約を選択すると、グループ鍵にはHOUR関数で十分です。あなたのコードに採用し、次のようにそれが見えるはずです。もちろん

public function findSortedToday() 
{ 
    $orders = $this->createQueryBuilder('o') 
     ->select('HOUR(o.createdAt) AS oCreated') 
     ->addSelect('SUM(od.dishPrice) AS odSum') 
     ->addSelect('os.name AS oShop') 
     ->innerJoin('o.shop', 'os') 
     ->innerJoin('o.dishes', 'od') 
     ->groupBy('oCreated') 
     // group by column name, not relation name 
     ->addGroupBy('oShop') 
     // limit to single day 
     ->where('o.createdAt = :day') 
     ->setParameter('day', $day) 
     ->getQuery() 
     ->getResult(); 
    return $orders; 
} 

、あなたが複数の日から選択することができますが、それに応じGROUP BYキーを調整する必要があります。

関連する問題