Multiply count for many items in query - mysql

This is my query:
SELECT
`i`.`itemtype` AS `Item`,
`p`.`name`
SUM(`i`.`count`) AS `Count`
FROM `player_items` AS `i`
LEFT JOIN `players` AS `p` ON (`p`.`id` = `i`.`player_id`)
WHERE `i`.`itemtype` IN (2148, 2152, 2160)
AND `i`.`player_id` = " . intval ( $main_Char->getId() ) . "
GROUP BY `i`.`itemtype`
LIMIT 0, 30;
Is there a possibility to multiple a count for each items it select? I mean WHERE
i.itemtypeIN (2148, 2152, 2160)
It does SUM the count of all items of ID: 2148, 2152, 2160 I need it to do the same but additionally multiply the count of each item: 2148 * 10, 2152 * 1000, 2160 * 10000 and then display the results in the Count row.

Yes, you can SUM multiple columns at once:
SELECT i.itemtype AS Item
, p.name
, SUM(CASE
WHEN itemtype = 2148 THEN i.count
ELSE 0
END) * 10 AS Count
, SUM(CASE
WHEN itemtype = 2152 THEN i.count
ELSE 0
END) * 1000 AS Count1
, SUM(CASE
WHEN itemtype = 2160 THEN i.count
ELSE 0
END) * 10000 AS Count2
FROM player_items AS i
LEFT JOIN players AS p ON i.player_id = p.id
WHERE i.itemtype IN (2148, 2152, 2160)
GROUP BY i.itemtype ASC
LIMIT 0, 30
To SUM those three columns together, you could:
SELECT t.itemType AS Item, t.Count, t.Count1, t.Count2
, SUM(t.Count1, t.Count2, t.Count3) AS Total
FROM
(
SELECT i.itemtype AS Item
, p.name
, SUM(CASE
WHEN itemtype = 2148 THEN i.count
ELSE 0
END) * 10 AS Count
, SUM(CASE
WHEN itemtype = 2152 THEN i.count
ELSE 0
END) * 1000 AS Count1
, SUM(CASE
WHEN itemtype = 2160 THEN i.count
ELSE 0
END) * 10000 AS Count2
FROM player_items AS i
LEFT JOIN players AS p ON i.player_id = p.id
WHERE i.itemtype IN (2148, 2152, 2160)
GROUP BY i.itemtype ASC
LIMIT 0, 30
) AS t
Or you could add another CASE
SELECT i.itemtype AS Item
, p.name
, SUM(CASE
WHEN itemtype = 2148 THEN i.count
ELSE 0
END) * 10 AS Count
, SUM(CASE
WHEN itemtype = 2152 THEN i.count
ELSE 0
END) * 1000 AS Count1
, SUM(CASE
WHEN itemtype = 2160 THEN i.count
ELSE 0
END) * 10000 AS Count2
, SUM(CASE
WHEN itemtype = 2148 THEN (i.count * 10)
WHEN itemtype = 2152 THEN (i.count * 1000)
WHEN itemtype = 2160 THEN (i.count * 10000)
ELSE 0
END) AS Total
FROM player_items AS i
LEFT JOIN players AS p ON i.player_id = p.id
WHERE i.itemtype IN (2148, 2152, 2160)
GROUP BY i.itemtype ASC
LIMIT 0, 30

It's not very clear what you want. Perhaps this:
SUM(i.`count`) * COUNT(*) AS `Count`
or this:
SUM(i.`count`) * i.itemtype AS `Count`

Related

Explain me ways to understand this complex query

Can anyone help me to understand this big sql query. How do I break it down in small chunks to understand it ?
select t.Instrument as Instrument ,ClearingId as ClearingId,
ISNULL( PrevQty ,0) AS PrevQty,SettlePrice,
ISNULL(TodayBuyQty,0) as TodayBuyQty,
ISNULL( TodaySellQty ,0) AS TodaySellQty,
ISNULL(PrevQty +TodayBuyQty-TodaySellQty,0) as NetQty,
TodayBuyPrice, TodaySellPrice,LTP,PnL,Token
from
(
select Instrument,w.ClearingId as ClearingId,
ISNULL( PrevQty ,0) AS PrevQty,ISNULL(TodayBuyQty,0) as TodayBuyQty,
ISNULL( TodaySellQty ,0) AS TodaySellQty,
TodayAvgBuyPrice as TodayBuyPrice,TodayAvgSellPrice as TodaySellPrice,
LTP,PnL,w.Token
from
(
select Symbol as Instrument, ClearingId,
ISNULL(TodayBuyQty,0) as TodayBuyQty,
TodayAvgBuyPrice,
ISNULL( -TodaySellQty ,0) AS TodaySellQty,
TodayAvgSellPrice, NULL as LTP ,NULL as PnL ,
w.Token as Token
from
(
select Token, sum(Qty) as NetPositionQty, ClearingId,
sum(CASE WHEN Qty < 0 THEN Qty ELSE 0 END) as TodaySellQty,
sum(CASE WHEN Qty > 0 THEN Qty ELSE 0 END) as TodayBuyQty,
sum(CASE WHEN Qty < 0 THEN Qty * Price ELSE 0 END)
/
NULLIF(sum(CASE WHEN Qty < 0 THEN Qty ELSE 0 END), 0) as TodayAvgSellPrice,
sum(CASE WHEN Qty > 0 THEN Qty * Price ELSE 0 END)
/
NULLIF(sum(CASE WHEN Qty > 0 THEN Qty ELSE 0 END), 0) as TodayAvgBuyPrice
from
(
select m.Token,
(CASE WHEN ClearingId = 'SATP' THEN 'STRAITS' ELSE CASE WHEN ClearingId = 'BATP' THEN 'BPI' ELSE 'UOB' END END ) as ClearingId ,
Price/CAST(Multiplier AS float ) as Price,Qty
from
(
select Token , Exchange as ClearingId ,
LastTradePrice as Price ,
CASE WHEN Side = 'S' THEN -LastTradeQuantity ELSE LastTradeQuantity END as Qty
from Strategy_Orders
where ExchangeStatus in (9,10) )m
JOIN TokenMap t ON ( m.Token = t.Token)
UNION ALL
select m.Token, (CASE WHEN ClearingId = 'SATP' THEN 'STRAITS' ELSE CASE WHEN ClearingId = 'BATP' THEN 'BPI' ELSE 'UOB' END END ) as ClearingId ,
Price/CAST(Multiplier AS float ) as Price,
Qty
from
(
select Token , Exchange as ClearingId ,
LastTradePrice as Price ,
CASE WHEN Side = 'S' THEN -LastTradeQuantity ELSE LastTradeQuantity END as Qty
from Manual_Orders
where ExchangeStatus in (9,10) )m
JOIN TokenMap t ON ( m.Token = t.Token)
UNION ALL
select Token , ClearingId , TodayBuyPrice ,
TodayBuyQty as Qty
from EOD_Holdings
where CurrentDate =
( select top 1 CurrentDAte from EOD_Holdings
order by CurrentDAte desc
)
UNION ALL
select Token , ClearingId , TodaySellPrice ,
TodaySellQty as Qty
from EOD_Holdings
where CurrentDate = (
select top 1 CurrentDAte from EOD_Holdings
order by CurrentDAte desc
)
) x
group by Token,ClearingId) w
JOIN(select Token, Symbol from TokenMAp ) h on w.Token = h.Token
) w
FULL OUTER JOIN(
select Token, PrevQty , ClearingId
from EOD_Holdings
where CurrentDate = ( select top 1 CurrentDAte from EOD_Holdings order by CurrentDAte desc
)
) h
on w.Token = h.Token and w.ClearingId = h.ClearingId
)t
JOIN (
select * from LatestSettlePrices
) sp
on t.Instrument = sp.Instrument
You can break the query into chunks by looking at each subquery ("select ..." ) separately and running them to see the results. You need to start with the innermost queries that do not have other select statements in the "from" or "where" clause.
Also note that this query does not seem to be a clear, neither an optimal solution.
You would want to avoid using full outer joins and union all statements for the best performance.

[HY000][1111] Invalid use of group function

I have searched a lot ,but none of other questions with error 1111 solves my problem.
My needs are to count the distinct phone number of some id
The following code works:
SELECT
a.id_borrow_application,
count(DISTINCT c.phone_no) CVG_CALL_OUT_COUNTS_6M
FROM t_snow_borrow_application_id a
JOIN t_snow_call_mobile b
JOIN t_snow_call_record_201612 c ON
(
a.id_borrow_application = b.id_borrow_application
AND b.id = c.id_call_mobile
)
WHERE c.call_type = 0
GROUP BY a.id_borrow_application;
But when I want to write 4 similar queries together,the error in title
happens.
[HY000][1111] Invalid use of group function
SELECT
a.id_borrow_application,
sum(CASE WHEN call_type = 0
THEN count(DISTINCT c.phone_no)
ELSE 0 END) CVG_CALL_OUT_COUNTS_6M,
sum(CASE WHEN call_type = 0 AND c.days <= 30
THEN count(DISTINCT c.phone_no)
ELSE 0 END) CVG_CALL_OUT_COUNTS_1M,
sum(CASE WHEN call_type = 1
THEN count(DISTINCT c.phone_no)
ELSE 0 END) CVG_CALL_IN_COUNTS_6M,
sum(CASE WHEN call_type = 1 AND c.days <= 30
THEN count(DISTINCT c.phone_no)
ELSE 0 END) CVG_CALL_IN_COUNTS_1M
FROM t_snow_borrow_application_id a
JOIN t_snow_call_mobile b
JOIN t_snow_call_record_201612 c ON
(
a.id_borrow_application = b.id_borrow_application
AND b.id = c.id_call_mobile
)
GROUP BY a.id_borrow_application;
Do I have to write 4 queries?
You are nesting aggregate function which is not allowed in MySQL.
You don't actually need the sum function for count distinct phone_nos for different conditions. Take the count (distinct outside the case and remove sum function and else clause of the case.
Try this:
select a.id_borrow_application,
count(distinct case when call_type = 0 then c.phone_no end) CVG_CALL_OUT_COUNTS_6M,
count(distinct case when call_type = 0
and c.days <= 30 then c.phone_no end) CVG_CALL_OUT_COUNTS_1M,
count(distinct case when call_type = 1 then c.phone_no end) CVG_CALL_IN_COUNTS_6M,
count(distinct case when call_type = 1
and c.days <= 30 then c.phone_no end) CVG_CALL_IN_COUNTS_1M
from t_snow_borrow_application_id a
join t_snow_call_mobile b
join t_snow_call_record_201612 c on (
a.id_borrow_application = b.id_borrow_application
and b.id = c.id_call_mobile
)
group by a.id_borrow_application;

mysql sum case not working

I am working on a mysql query using sum case. The query works for some of the cases but not for one case.
select orders.orderid, campers.description, dealers.name, orders.act_delivery,
sum(case orderitems.std
when 0 then
(case when orderitems.price = 0 then retail_price.price * orderitems. qty else orderitems.price * orderitems.qty end)
when 1 then
(case when orderitems.origqty = 0 then
0 else
(case when orderitems.price = 0
then retail_price.price * (orderitems.qty - orderitems.origqty)
else orderitems.price * (orderitems.qty - orderitems.origqty)
end)
end)
when 2 then
0
else
(case when orderitems.deletedprice = 0 then retail_price.price * orderitems. qty else orderitems.deletedprice * orderitems.qty end)
end) as retail
from orderitems, orders, dealers, campers, products, retail_price
where orderitems.orderid = orders.orderid
and orderitems.productid = products.prodid
and orderitems.productid =retail_price.prodid
and orders.dealerid = retail_price.dealer
and orders.dealerid = dealers.dealerid
and orders.camper = campers.camperid
and act_delivery > 0
and orderitems.std in (0, 1, 2)
and orders.dealerid not in (1, 9, 10, 12,15,16)
and spares_od = 0
and orders.act_delivery > '2016-10-01'
and orders.act_delivery <= '2016-10-31'
group by orders.orderid,orders.dealerid, orders.act_delivery order by orders.act_delivery, orders.orderid
The problem occurs when orderitems.std = 3. In either case I cannot get a result.
All other cases appear to be working correctly.

how to calc difference between two column with results

Could i calc for each row column Profit ?
SELECT
SUM(CASE WHEN m.billable = 0 THEN r.rate ELSE 0 END) AS Revenue, -- 33 + 34 + 456 + 52...etc = 5500
SUM(CASE WHEN m.billable = 1 AND m.optimized = 0 THEN r.rate ELSE 0 END) AS Costs,-- 33 + 4...etc = 339
5500 - 339 AS Profit -- I need to get this difference
FROM messages AS m
JOIN rates AS r ON (r.id = m.rate_id )
GROUP BY
m.client_account_id,
m.mcc,
m.mnc
I want to get
| Revenue | Costs | Profit
5500 500 5000
Move your query into a subquery, then subtract the results.
SELECT Revenue, Costs, Revenue - Costs AS Profit
FROM (
SELECT
SUM(CASE WHEN m.billable = 0 THEN r.rate ELSE 0 END) AS Revenue,
SUM(CASE WHEN m.billable = 1 AND m.optimized = 0 THEN r.rate ELSE 0 END) AS Costs
FROM YourTable) AS x
Joining your two tables, and showing the results grouped by account, it would be:
SELECT client_account_id, mmc, mnc, Revenue, Costs, Revenue - Costs AS Profit
FROM (
SELECT
m.client_account_id, m.mmc, m.mnc
SUM(CASE WHEN m.billable = 0 THEN r.rate ELSE 0 END) AS Revenue,
SUM(CASE WHEN m.billable = 1 AND m.optimized = 0 THEN r.rate ELSE 0 END) AS Costs
FROM messages AS m
JOIN rates AS r ON r.id = m.rate_id
GROUP BY m.client_account_id, m.mmc, m.mnc
) AS x
Simply put it in a sub query :
SELECT Revenue - Costs as Profit
FROM (
SELECT
SUM(CASE WHEN m.billable = 0 THEN r.rate ELSE 0 END) AS Revenue,
SUM(CASE WHEN m.billable = 1 AND m.optimized = 0 THEN r.rate ELSE 0 END) AS Costs
) as temp

Using MySQL Case for comparing dates

I need to tabulate the data from three tables for a report. Please see this query
SELECT
DATE( sale.sale_time ) AS dat,
location.location_name as location,
sale.sale_id AS total_orders,
SUM( CASE sale.is_cancelled WHEN 0 THEN sale.sale_amount ELSE 0 END ) AS sales,
SUM( CASE sale.is_cancelled WHEN 0 THEN sale.sale_discount ELSE 0 END ) AS discounts,
SUM( CASE sale.is_cancelled WHEN 0 THEN sale.sale_tax ELSE 0 END ) AS taxes,
COUNT( DISTINCT sale.customer_id ) AS total_customers,
SUM( CASE WHEN DATE( person.added_on ) = DATE( sale.sale_time ) THEN 1 ELSE 0 END ) AS new_customers,
SUM( CASE sale.is_cancelled WHEN 1 THEN 1 ELSE 0 END ) AS cancelled_orders
FROM
sales AS sale
INNER JOIN locations AS location ON location.location_id = sale.location_id
INNER JOIN people AS person ON person.person_id = sale.customer_id
GROUP BY
dat,location
The results for new_customers is showing wrong, often more than total_customers. Where is it wrong, and how to correct this?
The results are like this:
dat location total_orders sales discounts taxes new_customers total_customers cancelled_orders
15-03-14 Location1 52 1355 0 129.04 4 2 0
16-03-14 Location1 56 280 0 30 2 1 0
16-03-14 Location2 59 2518 0 212.2 3 6 2
As you might have guessed from the query, sales table has the columns sale_id,sale_time,sale_cost,sale_discount,sale_tax,sale_amount, is_cancelled (tinyint with values 0 or 1), and customer_id
People table has the columns person_id, first_name, added_on
By comparing the date(salessale_time) to date(person.added_on), I want to list customers added on that date
I modified the query to the following to get new customers also in the result set.
SELECT DATE(sale.sale_time) AS dat, location.location_name as location, (sale.sale_id) AS total_orders,
SUM(CASE sale.is_cancelled WHEN 0 THEN sale.sale_amount ELSE 0 END) AS sales,
SUM(CASE sale.is_cancelled WHEN 0 THEN sale.sale_discount ELSE 0 END) AS discounts,
SUM(CASE sale.is_cancelled WHEN 0 THEN sale.sale_tax ELSE 0 END) AS taxes,
count(distinct(sale.customer_id)) AS total_customers,
(select count(person_id) from people where date(added_on) = date(sale.sale_time) and person_id = sale.customer_id) as new_customers,
SUM(CASE sale.is_cancelled WHEN 1 THEN 1 ELSE 0 END) AS cancelled_orders
FROM sales AS sale
INNER JOIN locations AS location ON location.location_id = sale.location_id
GROUP BY dat,location;