Reputation: 1
I am trying to apply discounts to various totals. Each discount has its own discount code so I want to apply the code to its equivalent total. But sometimes this code can appear more than once. If so, I want to sum the discount codes to produce one discount.
My first attempt was this which was not correct but shows exactly what I just tried to explain, ie. discount codes appearing more than once:
SELECT bdto.dto_fac_cod_descuento,
COUNT(bdto.dto_fac_cod_descuento) howmany,
CASE
WHEN COUNT(bdto.dto_fac_cod_descuento) > 1
THEN ABS (ROUND (SUM(bdto.dto_fac_importe_dto), 0))
ELSE ABS (ROUND (bdto.dto_fac_importe_dto, 0))
END AS descuento
FROM
bren_descuentos bdto
GROUP BY bdto.dto_fac_cod_descuento, bdto.dto_fac_importe_dto
dto_fac_cod_descuento howmany descuento
714 1 4274.00
X23 1 4040.00
X23 1 3300.00
X23 1 2800.00
336 1 2584.00
E35 1 2519.00
713 1 1458.00
335 1 920.00
G07 1 610.00
M48 1 350.00
715 1 310.00
368 2 450.00
G07 1 94.00
168 1 70.00
349 1 62.00
X73 1 20.00
BN3 1 10.00
M47 1 2.00
A40 2 0.00
S11 1 0.00
After much deliberation, I currently have the following query which gives me the right answer (I doubt the code is the best it could be but that doesn't concern me right now)
SELECT bdto.dto_fac_cod_descuento,
CASE
WHEN COUNT(bdto.dto_fac_cod_descuento) > 1
THEN
ABS (ROUND (SUM(bdto.dto_fac_importe_dto), 0))
ELSE
(SELECT ABS (dto_fac_importe_dto) FROM bren_descuentos bd
WHERE bdto.dto_fac_cod_descuento = bd.dto_fac_cod_descuento)
END AS descuento
FROM
bren_descuentos bdto
GROUP BY bdto.dto_fac_cod_descuento
dto_fac_cod_descuento descuento
168 70.44
335 919.85
336 2584.31
349 62.16
368 450.00
713 1458.05
714 4273.73
715 309.62
A40 0.00
BN3 10.00
E35 2519.00
G07 704.00
M47 2.46
M48 349.77
S11 0.00
X23 10140.00
X73 20.00
My problem is I need to join another table as this query is just part of what I need and when I apply the JOIN, my results go haywire and I dont know how to fix it!
With the JOIN applied I get this:
SELECT bdto.dto_fac_cod_descuento,
CASE
WHEN COUNT(bdto.dto_fac_cod_descuento) > 1
THEN
ABS (ROUND (SUM(bdto.dto_fac_importe_dto), 0))
ELSE
(SELECT ABS (dto_fac_importe_dto) FROM bren_descuentos bd
WHERE bdto.dto_fac_cod_descuento = bd.dto_fac_cod_descuento)
END AS descuento
FROM bren_detalle bdet
JOIN
bren_descuentos bdto
ON bdet.det_unidad_medida = 'megabytes'
GROUP BY bdto.dto_fac_cod_descuento
dto_fac_cod_descuento descuento
168 318177.00
335 4154962.00
336 11673328.00
349 280777.00
368 2032650.00
713 6586012.00
714 19304438.00
715 1398554.00
A40 0.00
BN3 45170.00
E35 11378323.00
G07 3179968.00
M47 11112.00
M48 1579911.00
S11 0.00
X23 45802380.00
X73 90340.00
@Dukeling "Full" code with JOIN:
SELECT bdet.det_tipo_trafico tipo_trafico,
COUNT (bdet.det_tipo_trafico) total_numero,
ROUND (SUM (bdet.det_cantidad_medida_originada + bdet.det_cantidad_medida_recibida), 0) total_megas,
ROUND (SUM (bdet.det_importe), 2) total_importe,
ABS (ROUND (SUM(bdto.dto_fac_importe_dto), 0)) AS descuento,
ROUND ((SUM (bdet.det_cantidad_medida_originada + bdet.det_cantidad_medida_recibida)) / NULLIF (COUNT (bdet.det_tipo_trafico), 0), 0) mb_conxn
FROM bren_detalle bdet
JOIN
bren_descuentos bdto
ON bdet.det_unidad_medida = 'megabytes'
AND bdet.dto_fac_cod_descuento = bdto.dto_fac_cod_descuento
GROUP BY bdet.det_tipo_trafico, bdto.dto_fac_importe_dto, bdto.dto_fac_cod_descuento
Gives this result:
tipo_trafico total_numero total_megas total_importe descuento mb_conxn
DATOS EN ITINERANCIA 224 2176 653,88 0.00 10
MENSAJES MULTIMEDIA EN ITINERA 1 0 0,7 10.00 0
DATOS INTERNET 4389 38338 1789,19 412566.00 9
MENSAJES MULTIMEDIA 15 2 6,36 37785.00 0
DATOS INTERNET 4389 38338 1789,19 2677290.00 9
As you can see I get two "DATOS INTERNET" because there are two different values for descuento, it diesnt sum them. Also it still gives a HUGE number for the discounts, it is summing too many times.
Example of contents of bren_detalle (there are more columns but I am not using them)
det_tipo_trafico det_unidad_medida det_importe dto_fac_cod_descuento dto_fac_cod_descuento2
TRAFICO NAC.OTROS OPER.MOVILES Minutos 3,6588 714 368
TRAFICO NAC.OTROS OPER.MOVILES Minutos 1,4035 714 368
DATOS INTERNET Megabytes 0,0583 G07 NULL
TRAFICO NAC.OTROS OPER.MOVILES Minutos 8,756 714 368
TRAFICO NAC.OTROS OPER.MOVILES Minutos 0,5195 714 368
DATOS INTERNET Megabytes 0,0097 G07 NULL
INTERNO CORPORATIVO Minutos 0,1758 335 368
INTERNO CORPORATIVO Minutos 0,2617 335 368
TRAFICO NAC.OTROS OPER.MOVILES Minutos 1,8313 714 368
INTERNO MOVILES Minutos 1,5993 336 368
TRAFICO NAC.OTROS OPER.MOVILES Minutos 1,2165 714 368
INTERNACIONAL Minutos 1,541 M48 NULL
TRAFICO NAC.OTROS OPER.MOVILES Minutos 1,2108 714 368
DATOS INTERNET Megabytes 0,3351 G07 NULL
DATOS INTERNET Megabytes 0,9028 G07 NULL
DATOS INTERNET Megabytes 0,0102 G07 NULL
RESTO DE TRAFICO NACIONAL Minutos 2,4196 715 368
DATOS INTERNET Megabytes 0,0271 G07 NULL
TRAFICO NAC.OTROS OPER.MOVILES Minutos 2,8372 714 368
DATOS INTERNET Megabytes 0,1574 G07 NULL
Contents of bren_descuentos table (again there are more columns but not used):
dto_fac_cod_descuento dto_fac_importe_dto
S11 0.00
A40 0.00
BN3 -10.00
G07 -94.00
X23 -4040.00
168 -70.44
335 -919.85
336 -2584.31
349 -62.16
368 -225.00
368 -225.00
713 -1458.05
714 -4273.73
715 -309.62
A40 0.00
E35 -2519.00
M47 -2.46
M48 -349.77
X23 -3300.00
G07 -610.00
X23 -2800.00
X73 -20.00
To give an example, discount code G07 goes with DATOS INTERNET traffic so I should have 610+94=704 total discount.
Upvotes: 0
Views: 208
Reputation: 55619
It does depend what bren_detalle
looks like, but you probably need to specify a field to JOIN
on (otherwise it will basically be a CROSS JOIN
- one row matched to each other row in the other table):
bren_detalle bdet
JOIN bren_descuentos bdto
ON bdet.somefield = bdto.someotherfield
AND bdet.det_unidad_medida = 'megabytes'
Note that the reason you were getting unwanted results in the first query is because of dto_fac_importe_dto
in the GROUP BY
. This would result in a row for every distinct combination of dto_fac_cod_descuento
and dto_fac_importe_dto
. Just remove it and it should work: (also the CASE
seems a bit redundant)
SELECT bdto.dto_fac_cod_descuento,
COUNT(bdto.dto_fac_cod_descuento) howmany,
ABS (ROUND (SUM(bdto.dto_fac_importe_dto), 0)) AS descuento
FROM bren_descuentos bdto
GROUP BY bdto.dto_fac_cod_descuento
EDIT:
The problem is the your tables looks something like:
table 1 table 2
f1 f2 f1 f3
1 8 1 10
1 9 1 11
Then, when you JOIN
on f1 you get 4 rows, one for each combination of rows matching. Thus SUM(f2)
= (8+9)*2 (2 rows in table 2).
There may be more efficient ways, but the only way I can think of right now to fix it:
...
FROM (SELECT dto_fac_cod_descuento, SUM(someField), SUM(someOtherField)
FROM bren_detalle
WHERE det_unidad_medida = 'megabytes'
GROUP BY dto_fac_cod_descuento) bdet
JOIN
(SELECT dto_fac_cod_descuento, SUM(someField), SUM(someOtherField)
FROM bren_descuentos
GROUP BY dto_fac_cod_descuento) bdto
ON bdet.dto_fac_cod_descuento = bdto.dto_fac_cod_descuento
Upvotes: 1