I am building a query which needs to output a multiplication result of two fields as a currency value. 0.00 - 9999.99.
I have attempted several suggested solutions and so far either they give syntax errors or will round to a whole number with no decimal
Do I need separate the multiplication from the formatted result?
My current query.
mysql> SELECT b.RowNumber,b.Email, z.PriceMultiplier * p.Price
-> FROM Production p JOIN Performace pe ON p.Title = pe.Title
-> JOIN Booking b ON b.PerfDate = pe.PerfDate AND b.Perftime = pe.PerfTime
-> JOIN Seat s ON s.RowNumber = b.RowNumber
-> JOIN Zone z ON z.Name = s.Zone;
+-----------+----------------------+-----------------------------+
| RowNumber | Email | z.PriceMultiplier * p.Price |
+-----------+----------------------+-----------------------------+
| Z16 | Jane.Dot#live.com | 60 |
| Z18 | ZP#email.com | 60 |
| Z19 | ZP#email.com | 60 |
| U19 | Jane.Dot#live.com | 26.999999284744263 |
| U20 | Jane.Dot#live.com | 26.999999284744263 |
| X13 | Mike.Stand#email.com | 26.999999284744263 |
| X14 | Mike.Stand#email.com | 26.999999284744263 |
| Z19 | qvf3#live.com | 60 |
+-----------+----------------------+-----------------------------+
Datatypes - PriceMultiplier FLOAT NOT NULL and Price DECIMAL(6,2) NOT NULL
The TRUNCATE command appears to be most recommended however it is rounding
26.999999284744263 - should become 26.99 , not 27
You need the function TRUNCATE():
TRUNCATE(p.BasicTicketPrice * z.PriceMultiplier, 2)
For example:
select truncate(26.999999284744263, 2)
returns
26.99
Use MySQL's Round function in your query - ROUND(number, decimals)
e.g. SELECT ProductName, Price, ROUND(Price, 1) AS RoundedPrice
FROM Products; - Taken from https://www.w3schools.com/sql/func_mysql_round.asp
For your particular query, try something like
SELECT b.RowNumber, b.Email, ROUND(p.BasicTicketPrice * z.PriceMultiplier,2) AS Price FROM Booking b
JOIN Performance pe ON pe.PerfDate = b.PerfDate AND b.PerfTime = pe.PerfTime
JOIN Production p ON pe.Title = p.Title JOIN Seat s ON b.RowNumber = s.RowNumber
JOIN Zone z ON s.Zone = z.Name WHERE s.Zone = z.Name;
Truncate also gives the answer you are after
SELECT Truncate(26.999999284744263, 2);
26.99
Good luck with your studies
After settings both data types to Float.
PriceMultiplier FLOAT NOT NULL and Price FLOAT NOT NULL
Truncate worked, without rounding.
U19 | Jane.Dot#live.com | 26.99 |
Related
What I'm trying to achieve is to fetch the latest date of another column based on the same msisdn (if there exists more than one msisdn that is linked to other imsis). (You can assume imsi is more of a unique column)
(Tables are simplified for demonstration purposes)
I've two tables like the following:
operator table
+--------+--------+---------------------+
| imsi | msisdn | last_accessed |
+--------+--------+---------------------+
| 74583 | 004442 | 2018-04-05 16:20:32 |
+--------+--------+---------------------+
| 94210 | 023945 | 2017-02-13 11:27:14 |
+--------+--------+---------------------+
| 59123 | 004442 | 2018-07-15 05:24:55 |
+--------+--------+---------------------+
| 61234 | 089923 | 2018-07-21 16:13:29 |
+--------+--------+---------------------+
customer table
+--------+--------------+---------------------+
| imsi | company_id | business_plan |
+--------+--------------+---------------------+
| 74583 | FEX | yearly |
+--------+--------------+---------------------+
| 94210 | AOH | trial |
+--------+--------------+---------------------+
| 59123 | BIOI | monthly |
+--------+--------------+---------------------+
| 61234 | OOX | simple |
+--------+--------------+---------------------+
The following result is what I aim for. If I search for 74583 it should return 2018-07-15 05:24:55.
+--------+--------------+---------------------+----------------------+
| imsi | company_id | business_plan | last_accessed_date |
+--------+--------------+---------------------+----------------------+
| 74583 | FEX | yearly | 2018-07-15 05:24:55 |
+--------+--------------+---------------------+----------------------+
The following query returns almost what I try to achieve but does not return the latest date according to the table above.
SELECT
cust.imsi,
cust.company_id,
cust.business_plan,
CASE
WHEN
(
SELECT MAX(subop.last_accessed)
FROM operator subop
WHERE subop.msisdn = op.msisdn
GROUP BY subop.msisdn
HAVING COUNT(*) > 1
)
THEN
op.last_accessed
ELSE
'Never'
END
AS last_accessed_date
FROM customer cust
INNER JOIN operator op
ON cust.imsi = op.imsi
WHERE cust.imsi = '74583';
We can try doing this using a correlated subquery in the select clause:
SELECT
c.imsi,
c.company_id,
c.business_plan,
(SELECT MAX(t.last_accessed) FROM operator t
WHERE t.msisdn = o.msisdn) last_accessed_date
FROM customer c
INNER JOIN operator o
ON c.imsi = o.imsi
WHERE c.imsi = '74583';
Follow the link below for a SQLFiddle demo.
Demo
This query will return the last_accessed_date for every imsi:
select
o1.imsi,
o1.msisdn,
max(o2.last_accessed) as last_accessed_date
from
operator o1 inner join operator o2
on o1.msisdn = o2.msisdn
group by
o1.imsi,
o1.msisdn
(I am joining the operators table with itself to get the last accessed date based on the msisdn column). Then you can join this query with the customer table:
select
c.imsi,
c.company_id,
c.business_plan,
coalesce(l.last_accessed_date, 'Never') as last_accessed_date
from
customer c left join (
select
o1.imsi,
o1.msisdn,
max(o2.last_accessed) as last_accessed_date
from
operator o1 inner join operator o2
on o1.msisdn = o2.msisdn
group by
o1.imsi,
o1.msisdn
) l on c.imsi = l.imsi
it can then be written in some different ways, but I think this is the easier to understand.
Please see a fiddle here http://sqlfiddle.com/#!9/0f080c/1
Try this
SELECT
cust.imsi,
cust.company_id,
cust.business_plan,
(
SELECT MAX(last_accessed) FROM operator AS a WHERE a.msisdn = op.msisdn
) AS last_accessed_date
FROM customer cust
INNER JOIN operator op
ON cust.imsi = op.imsi
WHERE cust.imsi = '74583'
I know, is duplicated, but I do not know how to do it without a single query. Here is my problem:
Description of the model:
The "t_factura_detalle" stores the details of an invoce.
The posible products for the invoce details are stored in "t_licencia".
The table "t_asignacion" stores the product of a invoice (for the moment, is not important to save the invoice id from which each product is assigned) than has be assigned to a pc "id_pc" (only one license for record in the table assign).
Process in which I need help:
When i do the assignation process, i need return a list in which i return "t_licencia.id_licencia" and "t_licencia.licencia_name", but i need to sustract all the licenses already asigned stored in the "t_asignation" table. An example:
"t_licencia":
+-------------+--------------------------+
| id_licencia | licencia_name |
+-------------+--------------------------+
| 6 | Adobe Photoshop CS6 Pro |
| 4 | Microsoft Office 2013 SP |
+-------------+--------------------------+
"t_factura_detalle":
+------------+---------------------+-------------+----------+
| id_factura | id_factura_licencia | id_licencia | cantidad |
+------------+---------------------+-------------+----------+
| 6 | 1 | 6 | 30 |
| 6 | 3 | 4 | 40 |
| 7 | 4 | 4 | 40 |
| 6 | 6 | 6 | 40 |
| 6 | 8 | 6 | 40 |
+------------+---------------------+-------------+----------+
So, the quantity of products (licenses) are:
+--------------------------+---------------+
| licencia_name | sum(cantidad) |
+--------------------------+---------------+
| Adobe Photoshop CS6 Pro | 110 |
| Microsoft Office 2013 SP | 80 |
+--------------------------+---------------+
# At the moment I do not care what invoice is associated,
# I just want to know the amount
select t_licencia.licencia_name, sum(cantidad)
from t_licencia, t_factura_detalle
where t_licencia.id_licencia = t_factura_detalle.id_licencia
group by licencia_name;
And a example of the "t_asignation":
+---------------+---------------------+-------+------------------+
| id_asignacion | id_factura_licencia | id_pc | fecha_asignacion |
+---------------+---------------------+-------+------------------+
| 2 | 3 | 1 | 2017-00-00 |
+---------------+---------------------+-------+------------------+
So, the "t_asignacion" points to an "t_facture_detalle" record, where are a product.
How can i return values only if the the {substraction of the [sum of the available licenses] and the [sum of assigned licenses]} is greater than 0 in a stored procedure or a simply query (preferably)?
I do not know if I explain well.
Thank so much!
If I understood correctly your question you want to select all the id_licensia who are not in t_licencia.
SELECT id_licencia,
licencia_name
FROM t_licencia t_l
LEFT JOIN t_factura_detalle tfd ON tfd.id_licencia = t_l.id_licencia
WHERE tfd.id_licencia IS NULL
If you need to display only the license key who aren't in t_asignation then :
SELECT t_l.id_licencia,
t_l.licencia_name
FROM t_licencia t_l
LEFT JOIN t_factura_detalle tfd ON tfd.id_licencia = t_l.id_licencia
LEFT JOIN t_asignation t_a ON t_a.id_factura_licencia = tfd.id_factura
WHERE t_a.id_factura_licencia IS NULL
Then for the sum :
SELECT t_l.id_licencia,
t_l.licencia_name,
SUM(cantidad)
FROM t_licencia t_l
LEFT JOIN t_factura_detalle tfd ON tfd.id_licencia = t_l.id_licencia
LEFT JOIN t_asignation t_a ON t_a.id_factura_licencia = tfd.id_factura
WHERE t_a.id_factura_licencia IS NULL
GROUP BY _l.id_licencia,
t_l.licencia_name
Finally i managed to do it in a query. It's not so pretty, but it works... I put it here in case can help to others with similar problems.
Thanks a lot to Raymond and Jean.
select totales_factura_detalle.id_factura_licencia, tl2.licencia_name
from (
select ta.id_factura_licencia,
count(tl.licencia_name) as usadas,
(select tfd2.cantidad
from t_factura_detalle tfd2
where tfd2.id_factura_licencia = ta.id_factura_licencia
) as disponibles
from t_asignacion ta, t_factura_detalle tfd, t_licencia tl
where ta.id_factura_licencia = tfd.id_factura_licencia
and tl.id_licencia = tfd.id_licencia
group by id_factura_licencia
) totales_factura_detalle, t_factura_detalle tfd3, t_licencia tl2
where disponibles > usadas
and tfd3.id_factura_licencia = totales_factura_detalle.id_factura_licencia
and tl2.id_licencia = tfd3.id_licencia;
I want to remove digit after decimal how to solve it?
My query is:
SELECT city_name,
Assignedto,
COUNT(Assignedto) AS TC,
CONCAT(count(CASE
WHEN STATUS = 'CLOSED' THEN 1
ELSE NULL
END) * 100 / count(1), '%') AS SC,
CONCAT(count(CASE
WHEN STATUS = 'PENDING' THEN 1
ELSE NULL
END) * 100 / count(1), '%') AS PC,
SUM(TIMESTAMPDIFF(MINUTE,Request_Date, Xetr))/60 AS WH,
(154440-sum(TIMESTAMPDIFF(MINUTE,Request_Date, Xetr))/60) AS VH,
CONCAT(COUNT(Feedback_Rate)/COUNT(Assignedto)*100,'%') AS Feed_Percent,
SUM(Feedback_Rate)/(count(Feedback_Rate)*5)*5 AS AVG_Feedback
FROM `it_service_ticket`
INNER JOIN `it_problem`ON `it_service_ticket`.`it_problem_id`=`it_problem`.`it_problem_id`
INNER JOIN `city_master` ON `it_service_ticket`.cityid=`city_master`.city_id
WHERE `it_service_ticket`.`xetr` BETWEEN '2016-04-01 12:00:00 AM' AND '2017-02-28 12:00:00 PM'
GROUP BY Assignedto
ORDER BY city_name ASC;
Output
+-------------------------+-------------------------+-------+------------+----------+------------+--------------+-----------+---------+
| City_Name | AssigneeTo | TC | SC | PC | WH | VH | Feedback | Average |
+-------------------------+-------------------------+-------+------------+----------+------------+--------------+-----------+---------+
| Ahmedabad | mahesh.patel#corp.in | 297 | 100.0000% | 0.0000% | 147.0667 | 154292.9333 | 43.4343% | 4.4031 |
| Ahmedabad | mahesh.patel#corp.in | 297 | 100.0000% | 0.0000% | 147.0667 | 154292.9333 | 43.4343% | 4.4031 |
If you want to round off decimal places, use ROUND(yourColumn,0) function.
So 13.78 will become 14
If you want to get rid of decimal places, user FLOOR(yourColumn)
So 13.78 will become 13
So for example
SUM(TIMESTAMPDIFF(MINUTE,Request_Date, Xetr))/60 AS WH
should be changed to
ROUND(SUM(TIMESTAMPDIFF(MINUTE,Request_Date, Xetr))/60,0) AS WH
Edit: This would take care of your %.
CONCAT(
ROUND(count(CASE
WHEN STATUS = 'PENDING' THEN 1
ELSE NULL
END) * 100 / count(1),0)
, '%') AS PC
Do the same for all the columns you need to remove decimal places.
You Should Use TRUNCATE() in Mysql for Example
SELECT TRUNCATE(525.668545, 3) -- 525.668
I've following table stuinfo
+------------+-------+-----------+
| Roll_no | Name | Lastname |
+------------+-------+-----------+
| 37032 | johny | bravo |
| 37034 | sam | smith |
+------------+-------+-----------+
and second one stu_attendace
+------------+-------+-----------+
| Roll_no | Name | month |
+------------+-------+-----------+
| -1 | total | 26 |
| 37032 | johny | 19 |
| 37034 | sam | 25 |
+------------+-------+-----------+
Total days are 26 , so johny's attendance is 73.03% and Sam's attendance is 95.03% .
So how can I show their Attendance with percentage by calculating at run-time and showing those values in new column 'per_attendace' which is actually not in database. like shown in below
+----------+--------+-----------+---------------+
| roll_no | name | last_name | per_attendace |
+----------+--------+-----------+---------------+
| 37032 | johny | bravo | xx % |
| 37034 | sam | smith | xx % |
+----------+--------+-----------+---------------+
You can easily do what you want, in the SELECT clause you can select a literal value, or a column name, or any valid expression.
Just JOIN the two tables, and then calculate the percent like this:
SELECT
i.roll_no,
i.name,
i.Lastname,
((a.month / 26) * 100) AS percent
FROM stuinfo AS i
INNER JOIN stu_attendance AS a ON i.Roll_no = a.Roll_no;
Note that:
There is no need to duplicate the column name in both the two tables, just remove it from the other table, and keep your tables normalized.
Don't store the total value like this as a value in the column.
Update:
If you want to select the value of the total from the database, you can do this:
SELECT
i.roll_no,
i.name,
i.Lastname,
((a.month / (SELECT month
FROM stu_attendace
WHERE name = 'total')) * 100) AS percent
FROM stuinfo AS i
INNER JOIN stu_attendance AS a ON i.Roll_no = a.Roll_no;
SQL Fiddle Demo
You can also set that total value as a variable instead of the correlated subquery, like this:
SET #total = 0;
SELECT month
FROM stu_attendace
WHERE name = 'total'
INTO #total;
Then:
SELECT
i.roll_no,
i.name,
i.Lastname,
ROUND(((a.month / #total) * 100), 2) AS percent
FROM stuinfo AS i
INNER JOIN stu_attendace AS a ON i.Roll_no = a.Roll_no;
I used the ROUND function to round the number to only two decimal values.
Updated SQL Fiddle Demo
Try this
select a.roll_no , a.name ,a.last_name,(b.month/26)*100 as per_attendace
from stuinfo as a join
stu_attendace as b on a.roll_no=b.roll_no
try
SELECT i.roll_no, i.name, i.Lastname, ((a.month / 26) * 100) AS percent
FROM stuinfo AS i
INNER JOIN stu_attendance AS a ON i.Roll_no = a.Roll_no;
Update #1: query gives me syntax error on Left Join line (running the query within the left join independently works perfectly though)
SELECT b1.company_id, ((sum(b1.credit)-sum(b1.debit)) as 'Balance'
FROM MyTable b1
JOIN CustomerInfoTable c on c.id = b1.company_id
#Filter for Clients of particular brand, package and active status
where c.brand_id = 2 and c.status = 2 and c.package_id = 3
LEFT JOIN
(
SELECT b2.company_id, sum(b2.debit) as 'Current_Usage'
FROM MyTable b2
WHERE year(b2.timestamp) = '2012' and month(b2.timestamp) = '06'
GROUP BY b2.company_id
)
b3 on b3.company_id = b1.company_id
group by b1.company_id;
Original Post:
I keep track of debits and credits in the same table. The table has the following schema:
| company_id | timestamp | credit | debit |
| 10 | MAY-25 | 100 | 000 |
| 11 | MAY-25 | 000 | 054 |
| 10 | MAY-28 | 000 | 040 |
| 12 | JUN-01 | 100 | 000 |
| 10 | JUN-25 | 150 | 000 |
| 10 | JUN-25 | 000 | 025 |
As my result, I want to to see:
| Grouped by: company_id | Balance* | Current_Usage (in June) |
| 10 | 185 | 25 |
| 12 | 100 | 0 |
| 11 | -54 | 0 |
Balance: Calculated by (sum(credit) - sum(debits))* - timestamp does not matter
Current_Usage: Calculated by sum(debits) - but only for debits in JUN.
The problem: If I filter by JUN timestamp right away, it does not calculate the balance of all time but only the balance of any transactions in June.
How can I calculate the current usage by month but the balance on all transactions in the table. I have everything working, except that it filters only the JUN results into the current usage calculation in my code:
SELECT b.company_id, ((sum(b.credit)-sum(b.debit))/1024/1024/1024/1024) as 'BW_remaining', sum(b.debit/1024/1024/1024/1024/28*30) as 'Usage_per_month'
FROM mytable b
#How to filter this only for the current_usage calculation?
WHERE month(a.timestamp) = 'JUN' and a.credit = 0
#Group by company in order to sum all entries for balance
group by b.company_id
order by b.balance desc;
what you will need here is a join with sub query which will filter based on month.
SELECT T1.company_id,
((sum(T1.credit)-sum(T1.debit))/1024/1024/1024/1024) as 'BW_remaining',
MAX(T3.DEBIT_PER_MONTH)
FROM MYTABLE T1
LEFT JOIN
(
SELECT T2.company_id, SUM(T2.debit) T3.DEBIT_PER_MONTH
FROM MYTABLE T2
WHERE month(T2.timestamp) = 'JUN'
GROUP BY T2.company_id
)
T3 ON T1.company_id-T3.company_id
GROUP BY T1.company_id
I havn't tested the query. The point here i am trying to make is how you can join your existing query to get usage per month.
alright, thanks to #Kshitij I got it working. In case somebody else is running into the same issue, this is how I solved it:
SELECT b1.company_id, ((sum(b1.credit)-sum(b1.debit)) as 'Balance',
(
SELECT sum(b2.debit)
FROM MYTABLE b2
WHERE b2.company_id = b1.company_id and year(b2.timestamp) = '2012' and month(b2.timestamp) = '06'
GROUP BY b2.company_id
) AS 'Usage_June'
FROM MYTABLE b1
#Group by company in order to add sum of all zones the company is using
group by b1.company_id
order by Usage_June desc;