简体   繁体   中英

How to select SAME Column in SAME Table With Different Where Condition Using Yii2 QueryBuilder

Consider a Table billdetail Like this

__id__|__bill_id__|__weight__|__typecode__|__metal_type__|
|  1  |    2      |    5     |     S      |     GOLD     |
|  2  |    2      |    2     |     R      |     GOLD     |
|  3  |    2      |    13    |     S      |     GOLD     |
|  4  |    3      |    5     |     S      |     SILVER   |
|  5  |    3      |    2     |     S      |     SILVER   | 
|  6  |    4      |    4     |     R      |     SILVER   |

I try to select weight from this table billdetail with different condition.

 $bill_details = BillDetails::find()->groupby('billdetails.bill_id');                  
 $bill_details->addSelect('sum(billdetails.weight) AS gold_s_w')->andWhere(['billdetails.typecode'=>'S'])->andWhere(['billdetails.metaltype'=>'gold']);
 $bill_details->addSelect('sum(billdetails.weight) AS gold_r_w')->andWhere(['billdetails.typecode'=>'R'])->andWhere(['billdetails.metaltype'=>'gold']);
 $bill_details->addSelect('sum(billdetails.weight) AS silver_s_w')->andWhere(['billdetails.typecode'=>'S'])->andWhere(['billdetails.metaltype'=>'silver']);
 $bill_details->addSelect('sum(billdetails.weight) AS silver_s_r')->andWhere(['billdetails.typecode'=>'R'])->andWhere(['billdetails.metaltype'=>'silver']);
 $result= $bill_details->asArray()->all();

Results empty cause condition didn't satisfying. its Not working It give the Rawquery-


SELECT sum(billdetails.weight) AS gold_s_w, sum(billdetails.weight) AS gold_r_w, sum(billdetails.weight) AS silver_s_w,  
sum(billdetails.weight) AS silver_s_r
FROM `billdetails` WHERE (((((((`billdetails`.`typecode`='S') AND (`billdetails`.`metaltype`='gold')) AND (`billdetails`.`typecode`='R'))
AND (`billdetails`.`metaltype`='gold')) AND (`billdetails`.`typecode`='S')) AND (`billdetails`.`metaltype`='silver'))
AND (`billdetails`.`typecode`='R')) AND (`billdetails`.`metaltype`='silver') GROUP BY `billdetails`.`bill_id` 
`````````````
How to give Respective Where clauses for Respective Selection . 

Your query is this (group by three columns):

SELECT `bill_id`, `typecode`, `metal_type`, SUM(weight) FROM `test` WHERE 1 GROUP BY `bill_id`, `typecode`, `metal_type`  

Or in Yii2:

$bill_details = BillDetails::find()
->select([
    'bill_id',
    'typecode',
    'metal_type',
    'SUM(weight) as sum_weight',
])
->groupby('bill_id, typecode, metal_type')
->asArray()
->all(); 

UPDATE: You can use inner select:

SELECT 
bill_id,
(SELECT SUM(weight) FROM test t1 WHERE t1.bill_id = t.bill_id AND t1.typecode = "S" AND t1.metal_type = "GOLD") as gold_s_w,
(SELECT SUM(weight) FROM test t1 WHERE t1.bill_id = t.bill_id AND t1.typecode = "R" AND t1.metal_type = "GOLD") as gold_r_w,
(SELECT SUM(weight) FROM test t1 WHERE t1.bill_id = t.bill_id AND t1.typecode = "S" AND t1.metal_type = "SILVER") as silver_s_w,
(SELECT SUM(weight) FROM test t1 WHERE t1.bill_id = t.bill_id AND t1.typecode = "R" AND t1.metal_type = "SILVER") as silver_r_w
FROM `test` t 
WHERE 1 
GROUP BY bill_id

In YII2 must be like:

$bill_details = BillDetails::find()
->select([
    'bill_id',
    '(SELECT SUM(weight) FROM bill_details bt2 WHERE bt2.bill_id = bill_details.bill_id AND bt2.typecode = "S" AND bt2.metal_type = "GOLD") as gold_s_w',
    '(SELECT SUM(weight) FROM bill_details bt2 WHERE bt2.bill_id = bill_details.bill_id AND bt2.typecode = "R" AND bt2.metal_type = "GOLD") as gold_r_w',
    '(SELECT SUM(weight) FROM bill_details bt2 WHERE bt2.bill_id = bill_details.bill_id AND bt2.typecode = "S" AND bt2.metal_type = "SILVER") as silver_s_w',
    '(SELECT SUM(weight) FROM bill_details bt2 WHERE bt2.bill_id = bill_details.bill_id AND bt2.typecode = "R" AND bt2.metal_type = "SILVER") as silver_r_w',
])
->groupby('bill_id')
->asArray()
->all(); 

Better solution for this type of scenarios

$bill_details->addSelect("sum(IF(billdetails.typecode = 'S' and billdetails.metaltype ='gold',billdetails.weight,0)) AS gold_s_w");
$bill_details->addSelect("sum(IF(billdetails.typecode = 'R' and billdetails.metaltype ='gold',billdetails.weight,0)) AS gold_r_w");
$bill_details->addSelect("sum(IF(billdetails.typecode = 'S' and billdetails.metaltype ='silver',billdetails.weight,0)) AS silver_s_w");
$bill_details->addSelect("sum(IF(billdetails.typecode = 'R' and billdetails.metaltype ='silver',billdetails.weight,0)) AS silver_s_r");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM