Get the minimum of 3 columns in Vertica - sql

In Vertica, how can I get a column that is the min of 3 existing columns? In the case of a all nulls it should return zero.
I've tried min() function, but realized that it's only returning min of a column.
I thought about a case statement but realized it would be super long to capture every combination of results and would be very resource intensive.
I appreciate any suggestions. Thank you!

Use LEAST to get the minimum value of multiple columns per row.
select least(coalesce(open_hrs_diff,0),coalesce(click_hrs_diff,0),coalesce(login_hrs_diff,0))
from tablename

Related

Is it possible to create more rows than original data using GROUPBY and COUNT(*)?

I have the following query:
SELECT "domain", site_domain, pageurl, count (*) FROM impressions WHERE imp_date > '20150718' AND insertion_order_id = '227363'
GROUP BY 1,2,3
It was an incorrectly conceived query this I understand, but it took over 30 minutes to run, while just pulling the data without a count and groupby took just 20 seconds.
My question being is it possible that there are more rows created than the original data set?
Thanks!
The only time that an aggregation query will return more rows than in the original data set is when two conditions are true:
There are no matching rows in the query.
There is no group by.
In this case, the aggregation query returns one row; without the aggregation you would have no rows.
Otherwise, GROUP BY combines rows together, so the result cannot be larger than the original data.
When you are comparing time spent for returning a result set, you need to distinguish between time to first row and time to last row. When you execute a simple SELECT, you are inclined to measure the time to the first row returned. However, a group by needs to process all the data before returning any rows (under most circumstances). Hence, it would be better to compare the time to the last row returned by the simple query.

SQL Min function on Date

How does Min function work on dates ? If 2 records have the same date and time stamp , the min function returns 1. Does it pull records based on when it was put into the table ?
MIN is an aggregate function so it will return 1 record in your question's case. Since the two records have the same date and timestamp it doesn't matter which date and timestamp are returned (they're the same). Finally, the time the records were inserted is not considered.
MIN() returns the smallest of all selected values of a column. It seems to me that your statement may simply be asking if a minimum exists.
Please post your sql statement.
possibly this is what you need:
SELECT MIN (date) AS "Min Date"
FROM tablename;
Elliot already expained it.
Just a sidenode, if you are using MySQL: MySQL allows to aggregate on a certain column, while fetching other columns without aggregation. (SQL Server does NOT allow that!)
Example:
date | name
2015-03-06 | A
2015-03-06 | B
Using SELECT Min(date), name FROM table on MySQL will return various results.
Sometimes it will be
2015-03-06 | A
sometimes
2015-03-06 | B
Docu:
When using this feature, all rows in each group should have the same
values for the columns that are omitted from the GROUP BY part. The
server is free to return any value from the group, so the results are
indeterminate unless all values are the same.
SQL Server will throw an error, that no aggregation has been performed on column name. See also http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html
MySQL works this way, cause sometimes grouping on the second column is not really required, for example:
SELECT MAX(id), user_id FROM posts WHERE user_id = 6
(There could be NO other user_id than 6, so aggregation is not required in MySQL - However not paying attention on THIS will lead to wrong results as example one shows.)

Cummulative sum in report

Hello All,
I am working on a report where I am doing calculations:
Let's take the first line as an example. In the remaining prior column we have 15 and in the taken column we have 0.5, so in the remaining column, we have 14.5.
Now the issue is to use the result in the remaining field and transfer it to the next line in the remaining prior column. So instead of having 14 we should be having 14.5.
Has anyone worked on something similar and guide me on how to work on this? I really want to learn how to solve such an issue.
The ANSI standard lag() function does exactly what you want. SQL tables represent unordered sets, so I need to assume that you have some column -- which I will call id -- that identifies the ordering of the rows.
The syntax for lag() is:
select t.*, lag(Remaining) over (order by 1) as prevRemaining
from table t;
If you have a database that does not support the ANSI standard window functions, you can get the same effect with a subquery. However, the syntax for that might vary slightly among databases.

How does the aggregation function work with group by

I do not understand the following (returns numbers of comments for articles with the newest ones dates):
SELECT `id_comment`,COUNT(*) AS `number`, MAX(`date`) AS `newest`
FROM `page_comments`
WHERE TO_DAYS( NOW() )-TO_DAYS(`date`) < 90
GROUP BY `id_comment`
ORDER BY `count` DESC,`newest` DESC
I dont understand how come that the MAX function will not return the MAX value of all the page_comments table? That it automatically takes only the max for the given group. When using MAX, I would expect it to return the highest value of the column. I dont understand how it works together with groupig.
You described the behavior yourself quite correctly already: it automatically takes only the max for the given group.
If you group, you do it (per usual) on every column in the result set, that is not aggregated (not using COUNT, SUM, MIN, MAX...)
That way you get distinct values for all non aggregated columns and the aggregated ones will yield a result that only takes the 'current' group into account.
I am just explaining it to the ground.
MAX() - An aggregate function(Works over the group of data).
If ""group by"" clause is NOT specified, the database implicitly groups the data(column specified) considering the entire result set as group.
If specified, it just groups the data(column) in the group logic specified.
It all boils down to analysis order:
FROM
ON
OUTER
WHERE
GROUP BY
CUBE | ROLLUP
HAVING
SELECT
DISTINCT
10 ORDER BY
TOP
so you first have the from clause
Then you cut the relevant rows via where ( so here your sentence : *I don't understand how come that the MAX function will not return the MAX value of all the page_comments* --fails)
then group it
Then you select it.
The max and aggregate functions apply on the data which is already filtered!

using SUM and presenting result as absolute (ABS)

I have both positive and negative numbers (money) in a column and need to:
SUM the total ie. SUM(myColumn) based on if the numbers are +/-
Present the result as an absolute ie. even though the result is -1234 it should be presented as 1234
SQL is not my trade as you probably notice but we've solved most other issues but this one so any help is appriciated. Keep in mind my skill level is very low
You will have to use a combination of the sum and abs aggregate functions in SQL. Since you want the absolute value of the sum, the sum function will need to be called inside the call to abs:
select abs(sum(columnName)) from table
That should work for both SQL Server, MySQL, and Oracle.
Try one (or more) of these
SELECT SUM(moneyColumn) FROM MyTable
SELECT SUM(ABS(moneyColumn) FROM MyTable
SELECT ABS(SUM(moneyColumn) FROM MyTable