SQL query multiplying SUM result by amount of inner elements - sql

I have a query that lists features, based on components status and availability
SELECT Brand.Id
, Brand.Name
, Brand.Impact
, Brand.Visibility
, Brand.Risk
, SUM(Brand.Impact + Brand.Visibility + Brand.Risk) AS Priority
FROM Brand
LEFT OUTER JOIN Type
ON Brand.Id = Type.FeatureId
LEFT OUTER JOIN Model
ON Type.Id = Model.SubFeatureId
LEFT OUTER JOIN TestingStatus
ON Model.StatusId = TestingStatus.Id
WHERE (Model.IsDeleted = 'False')
AND (Brand.IsDeleted = 'False')
AND (Type.IsDeleted = 'False')
AND (#TeamId = 0 OR Model.TeamId = #TeamId)
GROUP BY Brand.YearId, Brand.Id, Brand.Name, Brand.Impact, Brand.Visibility, Brand.Risk
HAVING (Brand.YearId = #YearId)
My results are as follow:
ID Name Impact Visibility Risk Priority
403 Chevy 1 2 3 48
404 Nissan 1 1 1 24
405 Toyota 3 2 1 42
Instead of
ID Name Impact Visibility Risk Priority
403 Chevy 1 2 3 6
404 Nissan 1 1 1 3
405 Toyota 3 2 1 6
Each of these brands have respectively 8, 8 and 7 models. Which means that my query is doing for all of them to calculate priority: Impact*models + Visibility*models + Risk*models.
How can I get my SQL query to not do that multiplication?
Thanks

Based on your comment and unless I am not understanding what you need, I don't think you need the SUM(). I think you just want the total for each model. Using the SUM() you are going to get the total for all records which it doesn't sound like you want. This would also remove your GROUP BY and HAVING
SELECT Brand.Id
, Brand.Name
, Brand.Impact
, Brand.Visibility
, Brand.Risk
, (Brand.Impact + Brand.Visibility + Brand.Risk) AS Priority
FROM Brand
LEFT OUTER JOIN Type
ON Brand.Id = Type.FeatureId
LEFT OUTER JOIN Model
ON Type.Id = Model.SubFeatureId
LEFT OUTER JOIN TestingStatus
ON Model.StatusId = TestingStatus.Id
WHERE (Model.IsDeleted = 'False')
AND (Brand.IsDeleted = 'False')
AND (Type.IsDeleted = 'False')
AND (#TeamId = 0 OR Model.TeamId = #TeamId)
AND (Brand.YearId = #YearId)

Related

How to get Odoo Inventory adjustment value through SQL

I am working on a custom stock valuation module and in one model I am trying to get adjustment value for a lot - product - warehouse wise of the previous day.
QUERY 1
SELECT COUNT(*)
FROM
(
SELECT stock_inventory.date AS stock_adjustment_date,
stock_move_line.lot_id,
stock_move_line.product_id,
SUM(stock_move_line.qty_done) total_stock_adjustment
FROM stock_move_line
LEFT JOIN stock_move ON stock_move_line.move_id = stock_move.id
LEFT JOIN stock_inventory ON stock_move.inventory_id = stock_inventory.id
WHERE stock_move.inventory_id IS NOT NULL
AND stock_move_line.location_id = 5
AND stock_move_line.location_dest_id = 13
AND stock_move_line.lot_id IS NOT NULL
GROUP BY stock_move_line.lot_id, stock_move_line.product_id, stock_inventory.date
ORDER BY total_stock_adjustment DESC
)
testTable;
QUERY 2
SELECT COUNT(*)
FROM
(
SELECT stock_inventory.date AS stock_adjustment_date,
stock_move_line.lot_id,
stock_move_line.product_id,
SUM(stock_move_line.qty_done) total_stock_adjustment
FROM stock_move_line
LEFT JOIN stock_move ON stock_move_line.move_id = stock_move.id
LEFT JOIN stock_inventory ON stock_move.inventory_id = stock_inventory.id
WHERE stock_move.inventory_id IS NOT NULL
AND stock_move_line.location_id = 13
AND stock_move_line.location_dest_id = 5
AND stock_move_line.lot_id IS NOT NULL
GROUP BY stock_move_line.lot_id, stock_move_line.product_id, stock_inventory.date
ORDER BY total_stock_adjustment DESC
)
testTable;
Why these both queries returning same count 14,849 ?
13 is the warehouse ID and 5 is the virtual location used for adjustment. What I am doing wrong here?

SQL how sum if value

Hi I try to need to sum values and if there is more than 20 there shouldbe written 20 else should be number.
I don't know what i make wrong:
SELECT
ta6.product_product_id AS ID,
ta6.product_manufacture_code AS Code,
SUM(CASE WHEN ta3.stock_quantity >= 20 THEN 20 ELSE ta3.stock_quantity END) AS Quantity,
ta4.price_value AS Price,
ta5.Attribute_Value AS Sizer,
ta6.Procut_product_name AS Name,
ta7.Attribute_Value AS produce
FROM
product ta6
LEFT JOIN stock ta3 ON
ta3.stock_id = ta6.product_id
LEFT JOIN price ta4 ON
ta4.price_id = ta6.product_id
AND ta4.price_type = 2
LEFT JOIN Attributes ta5 ON
ta5.Attributes_product_Id = ta6.product_id
LEFT JOIN Attributes ta7 ON
ta7.Attributes_product_Id = ta6.product_id
WHERE
( ta3.stock_wharehouse_id = 1
AND ta5.Attrib_id = 54
AND ta7.Attrib_id = 25 )
GROUP BY
ta6.product_manufacture_code,
ta6.product_product_id
ta4.price_value,
ta5.Attribute_Value,
ta6.product_product_name ,
ta7.Attribute_Value;
Table stock_quantity looks like:
Stock_table image
How to sum it ??
Like this?
CASE WHEN SUM(ta3.stock_quantity) >= 20
THEN 20
ELSE SUM(ta3.stock_quantity)
END AS Quantity

Nesting Queries to get multiple column results

Have two queries , one collects moves in based on property and unit type the other would collect based on Move Outs for the same data. when ran separately they yield the correct information (move outs are 6 and move ins are 11) Have tried nesting in select and from statements but not getting what i need. When nested within the select am getting the correct move outs per unit type, but each line for move ins is total move ins. I recall that the nesting here would only return one value but know there is a way to return the value for each row. Any assistance is appreciated.
SELECT
p.scode as PropNumber,
p.saddr1 propname,
ut.scode as UnitType,
COUNT(t.hmyperson) as Moveouts,
(
SELECT COUNT(t.hmyperson) as MoveIns
FROM
tenant t
JOIN unit u ON t.hunit = u.hmy
JOIN property p ON p.hmy = u.hproperty
JOIN unittype ut ON ut.hmy = u.HUNITTYPE
WHERE
t.dtmovein >= getdate() - 14
AND p.scode IN ('gsaff')
) mi
FROM
Property p
JOIN unit u ON u.hproperty = p.hmy
JOIN tenant t ON t.hunit = u.hmy
JOIN unittype ut ON ut.hmy = u.HUNITTYPE
WHERE
p.scode IN ('gsaff')
AND t.DTMOVEOUT >= getdate()- 14
GROUP BY
ut.scode,
p.scode,
p.saddr1
With this data is coming out like :
PropNumber Propname UnitType MoveOuts MoveIns
1 x tc2 1 11
1 x tc3 2 11
1 x tc4 1 11
1 x tc5 1 11
1 x tc6 1 11 <pre>
Move in column should display as
2
5
1
0
3
You need to correlate the subquery according to the record being processed in the outer query. This also requires that you use different table aliases in the subquery than in the outer query.
It is hard to tell without seeing sample data, however I would expect that you need to correlate with all non-aggregated columns in the outer query.
Try changing :
(
SELECT COUNT(t.hmyperson) as MoveIns
FROM
tenant t
JOIN unit u ON t.hunit = u.hmy
JOIN property p ON p.hmy = u.hproperty
JOIN unittype ut ON ut.hmy = u.HUNITTYPE
WHERE
t.dtmovein >= getdate() - 14
AND p.scode IN ('gsaff')
) mi
To :
(
SELECT COUNT(t.hmyperson) as MoveIns
FROM
tenant t1
JOIN unit u1 ON t1.hunit = u1.hmy
JOIN property p1 ON p1.hmy = u1.hproperty
JOIN unittype ut1 ON ut1.hmy = u1.HUNITTYPE
WHERE
t1.dtmovein >= getdate() - 14
AND p1.scode IN ('gsaff')
AND p1.scode = p.scode
AND p1.saddr1 = p.saddr1
AND ut1.scode = ut.scode
) mi

Select Parent and Child if child has records

I have 3 tables: firearms_firearmbook, inventory_inventory and inventory_inventorytransaction.
And i have 2 Cases:
If inventory_inventory Table has no inventory_inventorytransaction with item action of 16, show inventory_inventory record
If inventory_inventory Table has inventory_inventorytransaction with item action of 16, show inventory_inventory and inventory_inventorytransaction.item_action_id
The query bellow works for the first cause, but its not working for the second cause.
It should show smth like this:
-----------------------------------
| id | serial | action_id |
-----------------------------------
1 MAGUM
2 EAGLE
2 EAGLE 16
Query:
SELECT FB.id, INV.serial_number, INV.id, INVT.item_action_id FROM firearms_firearmbook AS FB
LEFT JOIN inventory_inventory AS INV ON INV.id = FB.item_id
LEFT JOIN inventory_inventorytransaction AS INVT ON INVT.item_id = INV.id AND INVT.item_action_id = 16
WHERE FB.store_id = 1
It seems that if there is an action 16 record for a given item, you need two records in the output: one with a blank in the third column, and one with 16 in the third column.
In that case you could do this:
with base as (
select fb.id,
inv.serial_number,
inv.id,
from firearms_firearmbook as fb
inner join inventory_inventory as inv
on inv.id = fb.item_id
where fb.store_id = 1
)
select base.*,
invt.item_action_id
from base
inner join inventory_inventorytransaction as invt
on invt.item_id = base.id
and invt.item_action_id = 16
union all
select base.*,
null
from base
order by 1, 2, 3, 4 desc
Hi I think this is what your after.
I've made a CASE statement for the two situation you describe. I wasn't sure what you column you wanted for 2) when you say "inventory_inventory" so I put the id column and you can change it for another column.
I've also removed INVT.item_action_id = 16 part of the inventory_inventorytransaction join as I don't think it's necessary as it is handled in the CASE statement.
SELECT
FB.id,
INV.serial_number,
INV.id,
INVT.item_action_id,
CASE
WHEN INVT.item_action_id = 16 THEN CAST(INV.id as VARCHAR) + ' ' + CAST(INVT.item_action_id as VARCHAR) -- This is Case 2
ELSE INV.record -- This is Case 1
END as answer
FROM firearms_firearmbook AS FB
LEFT JOIN inventory_inventory AS INV ON INV.id = FB.item_id
LEFT JOIN inventory_inventorytransaction AS INVT ON INVT.item_id = INV.id -- Removed JOIN on INVT.item_action_id = 16 and moved it to CASE
WHERE FB.store_id = 1;

How to get count of installments that customers paid or must paid in sql

I want to get the count of installments that customers already paid for each bill and how many installments they should pay either they paid parts of the installments or they didn't. I tried this code but I couldn't get the real result either I get paid installments of bill or wrong counts of paid installments.
SELECT
sb.op_id ,
sb.auto_bill_no as sales_bill_no ,
sb.installmnts_cont ,
sb.installmnts_cont - COUNT(cupa.installment_no) as installmnts_net ,
sb.bill_total
FROM sale_bill as sb
LEFT OUTER JOIN custmrs_paymnts as cupa ON
sb.installmnt = 1 AND
sb.installmnt_completed = 0 --AND sb.op_id = cupa.sales_bill_no
WHERE cupa.installment = 1
AND sb.custmr_id = #cstmr_no
AND cupa.custmr_id = #cstmr_no
group by sb.op_id , sb.auto_bill_no , sb.installmnts_cont , sb.bill_total
Sample data from sale_bill table :
op_id auto_bill_no installmnts_cont installmnt_completed bill_total
---------------------------------------------------------------------------
55 10 2 true 6000
56 11 2 false 4000
Sample data from custmrs_paymnts table :
money_amt installment sales_bill_no installment_no
-----------------------------------------------------------------
3000 true 55 1
3000 true 55 2
The desired results are:
sales_bill_no installmnts_cont installmnts_net bill_total
---------------------------------------------------------------------
55 2 0 6000
56 2 2 4000
I do see a problem with your join conditions. Like there really aren't any. I'm not sure if this will fix your problem but it is worth a try:
SELECT . . .
FROM sale_bill sb LEFT OUTER JOIN
custmrs_paymnts cupa
ON sb.custmr_id = cupa.custmr_id AND
cupa.installment = 1
WHERE sb.custmr_id = #cstmr_no AND
sb.installmnt = 1 AND
sb.installmnt_completed = 0
Some rules:
Tables should normally be joined on columns in the tables, in the ON clause.
Conditions on the first table of a LEFT JOIN should go in the WHERE.
Conditions on the second table of a LEFT JOIN should go in the ON.