来自交易表

时间:2015-08-04 13:29:26

标签: orm doctrine-orm zend-framework2 doctrine

我有兴趣了解在交易表中监控用户余额的最佳方式,其中交易是存款或取款。

我目前的表结构是:

private $id;
private $user;
private $type; //credit or debit
private $identity; //deposit, transfer, withdraw
private $amount;
private $description;
private $scoredFee; //fixed charge
private $commission; //% charge
private $method; //cc, wallet etc.
private $status;

要算出用户余额,我只需取所有积分的总和并减去所有借记的总和:

public function getUserBalance(User $userObject)
{
    $credits = $this->transactionRepository->createQueryBuilder('u')
        ->add('select','SUM(u.amount)')
        ->where('u.status = :status')
        ->andWhere('u.type = :type')
        ->andWhere('u.user = :userObject')
        ->setParameter('status' , 1)
        ->setParameter('type' , 1)
        ->setParameter('userObject' , $userObject)
        ->getQuery()
        ->getSingleScalarResult();

    $debits = $this->transactionRepository->createQueryBuilder('u')
        ->add('select','SUM(u.amount)')
        ->where('u.status = :status')
        ->andWhere('u.user = :userObject')
        ->andWhere('u.type = :type')
        ->setParameter('status' , 1)
        ->setParameter('userObject' , $userObject)
        ->setParameter('type' , 2)
        ->getQuery()
        ->getSingleScalarResult();

    $balance = $credits - $debits;

    if (null == $balance)
    {
        return 0;
    }

    return $balance;

}

我考虑的另一种方法是在users表中有一个固定的帐户余额,每次用户进行交易时都会计算出来。我唯一的保留是这个边缘情况不同步。

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以使用金额的解码(我猜想的总和或减去)来简化仅一个查询,如下所示:

public function getUserBalance(User $userObject)
{
    $qb = $this->transactionRepository->createQueryBuilder('u');

    $qb ->add('select','SUM(CASE WHEN u.type = 1 then u.amount ELSE -u.amount END)')
        ->where('u.status = :status')
        ->andWhere($qb->expr()->in('u.type', array(1,2)))
        ->andWhere('u.user = :userObject')
        ->setParameter('status' , 1)
        ->setParameter('userObject' , $userObject);

    $balance = $qb
        ->getQuery()
        ->getSingleScalarResult();

    return $balance;

}

希望这个帮助