SQL - Cast two alias in BigDecimal - mysql

SELECT SUM(IF(create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH), 1, 0)) AS lastmonth,
SUM(IF(create_month = MONTH(NOW() - INTERVAL 2 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 2 MONTH), 1, 0)) AS lastmonth2
FROM incident_view
WHERE customer_company_name = "Company"
Hello everyone,
how Can I cast the two results (lastmonth and lastmonth2, which are both Int) into the Bigdecimal type/double, or any other decimal type?
Would appreciate some help.
Cheers

You mentioned BigDecimal, which is a Java type, not a MySQL type. In any case, the documentation recommends using either a number of types, including the NUMERIC or DECIMAL MySQL type, to convert with Java's BigDecimal, so your cast might look something like this:
SELECT CAST(SUM(IF(create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH), 1, 0)) AS NUMERIC) AS lastmonth,
CAST(SUM(IF(create_month = MONTH(NOW() - INTERVAL 2 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 2 MONTH), 1, 0)) AS NUMERIC) AS lastmonth2
FROM incident_view
WHERE customer_company_name = "Company"

Use CAST( .. AS DECIMAL)
SELECT
CAST(SUM(IF(create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH), 1, 0)) AS DECIMAL) AS lastmonth,
CAST(SUM(IF(create_month = MONTH(NOW() - INTERVAL 2 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 2 MONTH), 1, 0)) AS DECIMAL) AS lastmonth2
FROM incident_view
WHERE customer_company_name = "Company"

Related

Number of Working Days between two dates[LOGIC]

I have a function is MySql which calculates the number of working dates between two given dates but I would like to know the logic that is being used in it.
The sql function is as follows:
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
;
ABS is used throughout to ensure each result is a positive integer, in case the dates are backward (if the start point is after the end point).
ABS(DATEDIFF(date2, date1)) + 1
DATEDIFF returns the integer number of calendar days between the dates of 2 datetime values (in effect setting time to 00:00:00+00000 on both dates). Because DATEDIFF uses date only the duration of the second day is lost, so add 1 to compensate.
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
Calculate the start of the week for both dates using ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY) and ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY) and then get the number of days between those dates. Divide that number by 7 gives the number of weeks spanned between the dates. Multiply that number by 2 gives number of weekend days involved in the span. Subtract those weekend days from the raw number of days previously calculated gives the overall number of weekdays between the dates.
However the given start/end datetimes may individually fall on a weekend day, so:
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
If one of the given dates is a Sunday, subtract 1
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7)
If one of the given dates is a Saturday, subtract 1
Resulting in the number of "workdays" where the workweek excludes Saturday & Sunday.
In case it is of interest, here is a query that breaks out each function or set of function calls as individual columns so you can trace each. Adjust the subquery supplying 2 dates to suit.
select
date1
, date2
, DATEDIFF(date2, date1) "datediff"
, ABS(DATEDIFF(date2, date1)) abs_datediff
, ABS(DATEDIFF(date2, date1)) + 1 diff_2end_dt
, DAYOFWEEK(date2) dt2_dow
, ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY) start_of_wk_dt2
, DAYOFWEEK(date1) dt1_dow
, ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY) start_of_wk_dt1
, DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY)) diff_wksby7
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) abs_diff_wksby7
, ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2 diff_wkends
, DAYOFWEEK(IF(date1 < date2, date1, date2)) dow_min
, DAYOFWEEK(IF(date1 > date2, date1, date2)) dow_max
from (
select date_add(now(), INTERVAL -34 DAY) as date1, date_add(now(), INTERVAL -2 DAY) as date2
) d

Compare two numbers and receive true or false?

select *, COUNT(*), DATE_FORMAT(CREATE_DATE,'%m-%Y') AS form_date
from incident_view
where (create_month = month(NOW() - INTERVAL 1 MONTH)
and (create_year = year(NOW() - INTERVAL 1 MONTH)))
OR (create_month = month(NOW() - INTERVAL 2 MONTH)
and (create_year = year(NOW() - INTERVAL 2 MONTH)))
AND CUSTOMER_COMPANY_NAME = "Company"
GROUP BY CREATE_MONTH
Hello everyone,
The query I have above is working fine.
The result I get are some rows, but the important rows are:
COUNT(*) | form_date
667 01-16
1964 02-16
I wonder if it's possible to compare the two counts of the last 2 months, whether the last month (02-16) > the second last month (01-16).
If 02-16 > 01-16 I want the result to be true, if not then false.
Would appreciate any help.
Regards.
Instead of grouping by the month/year, use it in a CASE or IF when calculating the counts.
SELECT SUM(IF(create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH), 1, 0)) >
SUM(IF(create_month = MONTH(NOW() - INTERVAL 2 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 2 MONTH), 1, 0)) AS count_higher
FROM incident_view
WHERE customer_company_name = "Company"
If you want 3 different results for greater than, equal to, or less than, the best way is to calculate the sums in a subquery so you can name them and use CASE to return different values for each case.
SELECT CASE WHEN last_month > prev_month THEN 1
WHEN last_month = prev_month THEN 2
ELSE 0
END AS diff
FROM (
SELECT SUM(IF(create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH), 1, 0)) AS last_month,
SUM(IF(create_month = MONTH(NOW() - INTERVAL 2 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 2 MONTH), 1, 0)) AS prev_month
FROM incident_view
WHERE customer_company_name = "Company"
) AS subquery
You could do something like
Select max(viewcount)
FROM (select * , COUNT(*) AS viewcount,
DATE_FORMAT(CREATE_DATE,'%m-%Y') AS form_date
from incident_view
Where (create_month = month(NOW() - INTERVAL 1 MONTH) and (create_year = year(NOW() - INTERVAL 1 MONTH)))
OR (create_month = month(NOW() - INTERVAL 2 MONTH) and (create_year = year(NOW() - INTERVAL 2 MONTH)))
AND CUSTOMER_COMPANY_NAME = "Company"
GROUP BY CREATE_MONTH);

SQL - Limit all Except TOP 6

the SQL I got at the moment and it is working :
SELECT Count(CATEGORY), COUNT(INCIDENT_ID), CATEGORY,
ROUND(Count(CATEGORY) * 100 / (SELECT Count(*)
FROM incident_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
), 1) AS Percentage
FROM incident_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY CATEGORY
ORDER BY COUNT(INCIDENT_ID) DESC
limit 6
This query results in the top 6 Categorys and their number of Incidents with the Percentage.
Now I want to generate a second query, which shows me all Category and their Total Number + Percentage , !EXCEPT! the 6 Category I retrieved in the first query.
So if I have let's say 20 Categorys, I now want number 7-20 Displayed, under one name "Other" and the total Number Sumed up of all Categories (7-20) + their Percentage.
The result should look like this for example:
Category| Number of Inicdents | Percentage
Other 200 20%
Other should Contain all categories, except the from the first query..
Is this Possible?
Would appreciate any help.
------------EDIT-------------
SELECT Count(CATEGORY), COUNT(INCIDENT_ID), CATEGORY,
ROUND(Count(CATEGORY) * 100 / (SELECT Count(*)
FROM incident_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
), 1) AS Percentage
FROM incident_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY CATEGORY
ORDER BY COUNT(INCIDENT_ID)DESC
limit 6, 1295852105
Cheers
As you don't know the last record so use just a large number as below code
SELECT Count(CATEGORY), COUNT(INCIDENT_ID), CATEGORY,
ROUND(Count(CATEGORY) * 100 / (SELECT Count(*)
FROM incident_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
), 1) AS Percentage
FROM incident_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY CATEGORY
ORDER BY COUNT(INCIDENT_ID) DESC
limit 6, 18446744073709551615;

Calculate group percentage to 1 decimal places - SQL

I have this SQL at the moment:
SELECT Count(create_weekday),
create_weekday,
Count(create_weekday) * 100 / (SELECT Count(*)
FROM call_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
) AS Percentage
FROM call_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY CREATE_WEEKDAY
ORDER BY (CASE CREATE_WEEKDAY
WHEN 'Monday' THEN 1
WHEN 'Tuesday' THEN 2
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 4
WHEN 'Friday' THEN 5
WHEN 'Saturday' THEN 6
WHEN 'Sunday' THEN 7
ELSE 100 END)
It's working and I received the result:
Count(create_weekday) | Create_Weekday | Percentage
225 Monday 28.0899
How do I round to only 1 decimal place?( Like 28.1)
Would appreciate any help
Use ROUND(Percentage, 1):
SELECT Count(create_weekday),
create_weekday,
ROUND(Count(create_weekday) * 100 / (SELECT Count(*)
FROM call_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
), 1) AS Percentage
FROM call_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY CREATE_WEEKDAY
ORDER BY (CASE CREATE_WEEKDAY
WHEN 'Monday' THEN 1
WHEN 'Tuesday' THEN 2
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 4
WHEN 'Friday' THEN 5
WHEN 'Saturday' THEN 6
WHEN 'Sunday' THEN 7
ELSE 100 END)
You can just use the built-in ROUND(N,D) function, the second argument is the number of digits.
MySQL Reference: http://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_round
You have several options. I would not recommend round(), because this doesn't really change the underlying representation.
You can convert the value to a string, using format(), or just convert the value to a decimal/numeric. This looks like:
SELECT . . .
CAST(Count(create_weekday) * 100 /
(SELECT Count(*)
FROM call_view
WHERE (create_month = Month(Now() - INTERVAL 1 month) ) AND
(create_year = Year( Now() - INTRVAL 1 month) ) AND
customer_company_name = 'Company'
) as DECIMAL(4, 1)
) as Percentage
As Jarlh stated, cast(Percentage as decimal(4,1)) sets this to a decimal value with 4 places and 1 fraction place. The column value of Percentage will be rounded into this criteria.

SQL - Percentage

I need to make a query, which results in a percentage.
The query I have at the moment looks like this:
select COUNT(CREATE_WEEKDAY),
CREATE_WEEKDAY,
COUNT(CREATE_WEEKDAY) * 100 /
from call_view
WHERE (create_month = MONTH(NOW() - INTERVAL 1 MONTH))
AND (create_year = YEAR(NOW() - INTERVAL 1 MONTH))
AND CUSTOMER_COMPANY_NAME = "Company"
group by CREATE_WEEKDAY
If I start the query the result shows:
COUNT(CREATE_WEEKDAY) | CREATE_WEEKDAY | COUNT(CREATE_WEEKDAY) * 100
111 Friday 11100
225 MONDAY 22500
and so on....
I want the last column to display the
"COUNT(CREATE_WEEKDAY) * 100 / SUM(COUNT(CREATE_WEEKDAY))"
->> this last part should be the SUM OF all the CREATE_WEEKDAY. In the example give = 111 + 225 = 336
But this Code isn't working. I appreciate any help.
Cheers
Here is one way using Sub-query
First identify the total count for the given filter's(where clause)
SELECT Count(*)
FROM call_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = 'Company'
Then use this query in denominator to find percentage
SELECT Count(create_weekday),
create_weekday,
Count(create_weekday) * 100 / (SELECT Count(*)
FROM call_view
WHERE
( create_month = Month(Now() -
INTERVAL 1 month) )
AND ( create_year = Year(
Now() - INTERVAL 1 month) )
AND customer_company_name =
'Company')
FROM call_view
WHERE ( create_month = Month(Now() - INTERVAL 1 month) )
AND ( create_year = Year(Now() - INTERVAL 1 month) )
AND customer_company_name = "Company"
GROUP BY create_weekday
Join with a subquery that calculates the total count.
select COUNT(*),
CREATE_WEEKDAY,
COUNT(*) * 100 / total_count
from call_view
CROSS JOIN (SELECT COUNT(*) AS total_count
FROM call_view
WHERE create_month = MONTH(NOW() - INTERVAL 1 MONTH)
AND create_year = YEAR(NOW() - INTERVAL 1 MONTH)
AND customer_company_name = "Company") AS x
WHERE (create_month = MONTH(NOW() - INTERVAL 1 MONTH))
AND (create_year = YEAR(NOW() - INTERVAL 1 MONTH))
AND CUSTOMER_COMPANY_NAME = "Company"
group by CREATE_WEEKDAY