What can one do in a SQL SUM expr? [duplicate] - mysql

This question already has answers here:
need to return two sets of data with two different where clauses
(2 answers)
Closed 5 years ago.
The documentation for the SQL SUM function lists its "signature" like this:
SUM([DISTINCT] expr)
The only examples listed for expr are single column names (like units, price, etc.), but can one do more with it? expr sounds very broad and open...
I'm especially interested in if it's possible to do any sort of selection of what exactly to sum. For example, I'd really like to do the following right now:
SELECT
SUM(hours) 'Hours total',
SUM(hours WHERE date BETWEEN '2017-10-01' AND '2017-10-31') 'Hours last month'
But that doesn't run... Probably too much of an expr dream, but maybe...? Maybe not?
Is anything like that possible with the SUM function? What can expr be?

Maybe you could use query like:
SELECT
SUM(hours) 'Hours total',
SUM( CASE WHEN date BETWEEN '2017-10-01' AND '2017-10-31'
THEN hours
ELSE 0 END) 'Hours last month'
from table

Related

Go Back To Beginning Of Month On Input Date MySQL [duplicate]

This question already has answers here:
How to get first day of every corresponding month in mysql?
(15 answers)
Closed 5 years ago.
Let's say that I have an input date of "2017-01-31" or "2017-02-28". I want to take this input date and make SQL change it to "2017-01-01" or "2017-02-01".
Is there a way to do this via MySQL functions in a query?
Several ways to do that. My preference is to use DATE_FORMAT to replace the day portion with constant 01.
SELECT DATE_FORMAT('2017-01-31','%Y-%m-01') + INTERVAL 0 DAY AS dt
There are lots of ways to skin that cat.
For example, we could subtract the integer number of days minus 1 ...
SELECT '2017-01-31' + INTERVAL 1-DAY('2017-01-31') DAY
(With the second form, the date value needs to be supplied twice. With the first, we only need to supply the value one time. I think the first form is easier for a future reader to understand... pretty clear what the author is intending.)
Use your date instead of my example:
SELECT CONCAT_WS('-',YEAR('2017-01-28'),MONTH('2017-01-28'),'01')

Select leave data from attendance table given the following condition

I have attendance data for employees stored in the table attendance with the following column names:
emp_id (employee ID)
date
type (leave, absent, etc.)
(there are others but I'm omitting them for the sake of simplicity)
My objective is to retrieve all dates of the given month on which the employee was on leave (type = 'Leave') and the last leave taken in the last month, if any.
It's easy to do it using two queries (I'm using PHP to get process the data), but is there any way this can be done in a single query?
I'm answering my own question so as to close it. As #bpgergo pointed out in the comments, UNION will do the trick here.
SELECT * FROM table_name
WHERE type="Leave" AND
date <= (CURRENT_DATE() - 30)
Select the fields, etc you want then se a combined where clause using mysql's CURRENT_DATE() function. I subtracted 30 for 30 days in a month.
If date is a date column, this will return everyone who left 1 month or longer ago.
Edit:
If you want a specific date, change the 2nd month like this:
date <= (date_number - 30)

SQL query to find the most common index of a minimal field [duplicate]

This question already has answers here:
ROW_NUMBER() in MySQL
(26 answers)
Closed 8 years ago.
I have a table that tracks the activity in several websites. Each row is of the following form: (Date, Hour, Website, Hits)
The Hour field is a number between 0 and 23 and represents an entire hour (for example, 22 is for any hits between 22:00 and 22:59).
I want to find the overall slowest hour for each website, meaning the input should be something like (Website, Hour).
In order to do that, I was thinking I should have a nested query to find the minimum hits for each website on each day, and then count the values of Hour (again, for each website on each day), and see which value is the maximal.
I'm still new to SQL so I'm having difficulties using the min() function properly, to find the minimal value only for a specific date and website. Then I have the same problem with using count() for a specific website.
I'm also curious if I can get not just the most common slowest hour, but maybe the 3 slowest, but at least to me it seems like it's really complicating the problem.
For the first nested query, I considered something like this:
SELECT DISTINCT Date Date_t, Website Website_t, Hour,
(SELECT min(Hits) from HITS_TABLE WHERE Date=Date_t and Website=Website_t) as MinHits
FROM HITS_TABLE
But not only it takes an abnormally long time to calculate, it also gives me multiple entries of (Date_t, Website_t, Hour, min(Hits)) for each value of Hour, so I take it that I'm not doing it in the smartest, nor the most efficient way.
Thanks in advance for any help!
You can get the minimum hour using a trick in MySQL:
select website, substring_index(group_concat(hour order by hits), ',', 1) as minhour
from table t
group by website;
For each website, this constructs a comma-delimited list of hours, ordered by the number of hits. The function substring_index() returns the first row.
This is something of a hack. In most other databases, you would use window/analytic functions, but these are not available in MySQL.
EDIT:
You can do this in standard SQL as well:
select t.*
from table t
where not exists (select 1
from table t2
where t2.hour = t.hour and
t2.hits < t.hits
);
This is interpreted as: "Get me all rows from the table where there are no other rows with the same hour and a lower number of hits." This is a round-about way of saying: "Get me the hour with the minimum value." Note that this will return multiple rows when there are ties.

SQL add comma seperators on an integer value [duplicate]

This question already has an answer here:
MySQL - Thousands separator
(1 answer)
Closed 9 months ago.
I have a query:
select sum(invoiceamount) as invoice
from fact_salescount
where year in ({YEAR})
and month >= ({FROMMONTH})
and month <= ({TOMONTH})
This query can return a value from 100.00 to 15034115.93. It will return ONE value.
I would like to add, for each 000, like this: 15,034,115.93
I've seen a lot of similar questions, but none match mine. I hope someone can help me out.
I am using Pentaho and MySQL, and creating these queries within the Design Studio.
SELECT FORMAT(sum(invoiceamount),2)
FROM fact_salescount
WHERE year IN ({YEAR})
AND month >= ({FROMMONTH})
AND month <= ({TOMONTH})
This should do what you want, but I still don't like formatting number in the backend.

How to get the greatest of two columns values in MySQL?

I'm trying to do something like this:
SELECT MAX(
ADDDATE(expirationdate, INTERVAL 1 YEAR),
ADDDATE(now(), INTERVAL 1 YEAR)
)
That is, get "a year from now", or "a year from the expiration date stored in the table", whichever is greater (i'm renewing people's subscriptions).
This obviously doesn't work, since MAX() is for aggregation between rows, not for comparing 2 values. Is there a function that'll do this in MySQL? (i'd like to avoid doing an IF)
greatest()