I am converting my MySql queries to run over Vertica database for one of our projects where we are facing problem with executing SUM aggregate function.
MYSQL Query:
SELECT event.plateNumber, event.plateCodeId, sum( event.sourceId
in (1,2,3) ) as 'sum' from event group by event.plateNumber, event.plateCodeId
having sum( event.sourceId in (1,2,3) ) > 0 ;
I am trying to run this query in vertica database and having below exception.
Error: Function sum(boolean) does not exist, or permission is denied for sum(boolean)
When we refer to vertica documentation about SUM aggregate function, it looks like there is no difference in function signature.
I tried to look over different sites but could not get any help to transform above mentioned MYSQL Query to vertica Query.
Can anyone help regarding that?
Thanks
What about...
SELECT
event.plateNumber,
event.plateCodeId,
sum((event.sourceId in (1,2,3))::INTEGER) as 'sum'
FROM
event
GROUP BY
event.plateNumber, event.plateCodeId
HAVING
sum((event.sourceId in (1,2,3))::INTEGER) > 0 ;
The sum() predicate is supported by Vertica, but doesn't support booleans.
You need to convert your boolean value to numeric first. Since cast doesn't known how to convert a boolean to numeric, your best option is to use a case. For example :
SELECT event.plateNumber,
event.plateCodeId,
sum( CASE WHEN event.sourceId in (1,2,3) THEN 1 ELSE 0 END) as 'sum'
FROM event
GROUP BY event.plateNumber, event.plateCodeId
Related
The following query works in MySQL:
SELECT
f.created_date as time_sec
,sum(f.value) as value
, date_format( f.created_date , '%a') as metric
FROM ck_view_fills as f
GROUP BY date_format(f.created_date, '%a' )
I have migrated my database to PostgreSQL and I am now converting my queries to match. My naive conversion looks like this:
SELECT
f.created_date as time_sec
,sum(f.value) as value
, to_char( f.created_date , "D") as metric
FROM ck_view_fills as f
GROUP BY to_char( f.created_date , "D")
This query is not accepted and the error message produced by PostgreSQL is the following:
Error in query (7): ERROR: column "f.created_date" must appear in the
GROUP BY clause or be used in an aggregate function LINE 2:
f.created_date as time_sec
As far as I can tell f.created_date is indeed used in the group by clause. I have also seen examples using this very syntax. So what is the cause of this error and how do I get around it?
Postgres is correct. In fact, your query would fail with the most recent versions of MySQL as well -- using the default settings.
Just use an aggregation function:
SELECT MIN(f.created_date) as time_sec,
SUM(f.value) as value
TO_CHAR(f.created_date, 'D') as metric
FROM ck_view_fills f
GROUP BY to_char(f.created_date , 'D');
You should have used a similar construct in MySQL (regarding MIN() -- or MAX()).
I have a table as follows:
log (log_id, log_success (bool), log_created)
I would like to SELECT and return 3 columns date success and no_success, where the former does not exist in table and finally aggregate them by day.
I have created this query:
SELECT
log_created as 'date'
COUNT(*) AS 'count',
SUM(log_success) AS 'success'
SUM('count' - 'success') AS 'no_success'
FROM send_log
GROUP BY DATE_FORMAT(log_created, '%Y-%m-%d');
Would I be able to achieve it with this query? Is my syntax correct?
Thanks.
You can't reuse an alias defined in the select within the same select clause. The reason for this is that it might not even have been defined when you go to access it. But, you easily enough can repeat the logic:
SELECT
log_created AS date,
SUM(log_success) AS success,
COUNT(*) - SUM(log_success) AS no_success,
FROM send_log
GROUP BY
log_created;
I don't know why you are calling DATE_FORMAT in the group by clause of your query. DATE_FORMAT is usually a presentation layer function, which you call because you want to view a date formatted a certain way. Since it appears that log_created is already a date, there is no need to call DATE_FORMAT on it when aggregating. You also should not even need in the select clause, because the default format for a MySQL date is already Y-m-d.
You must select DATE_FORMAT(log_created, '%Y-%m-%d') if you want to group by this.
Also you can get the no_success counter with SUM(abs(log_success - 1))
SELECT
DATE_FORMAT(log_created, '%Y-%m-%d') date,
SUM(log_success) log_success,
SUM(abs(log_success - 1)) no_success
FROM send_log
GROUP BY date;
See the demo
Previously I was using the MySQL. With that I was able to use the query below to get the maximum number from the database.
Here 'No' is the varchar(10):
SELECT max(cast(No as unsigned)) as No FROM `tableName` LIMIT 1
The above query working fine in MySQL. I want to do the same thing in the MS SQL. When I run the same query, I get the following error:
Warning: sqlsrv_fetch_array() expects parameter 1 to be resource, boolean given
Any advice on this?
There is no LIMIT in SQL Server, no unsigned datatype, and no need to quote the table name.
Does this work:
SELECT max(cast(No as bigint)) as No FROM tableName
I'm trying to sum all the values for a field up to a designated 'max_value'. Once the SUM() function hits the 'max_value', no more values will be added to the sum.
SUM(CASE WHEN (this_expr <= max_value) THEN table.field ELSE 0 END) AS this_expr, ...
Is this possible? What should this_expr be? What should the proper syntax look like.
I realize that from this example it would be easier to perform a "CASE WHEN (SUM(table.field) > max_value) THEN max_value ELSE SUM(table.field) END" however the main goal is to be able to reference the this_expr field/variable within other CASE functions within the select. Kinda like capturing the exact instance in which the this_expr has reached the max_value
Any help is much appreciated
is it possible to get the average value for a column, as well as the average value for the same column with a conditional? or simply to combine these two queries into one.
SELECT AVG( field ) from table
SELECT AVG ( field ) from table where col = some_val
If there isn't a simple way to combine them using native mysql functions, would a stored function be able to handle it, or a user defined function?
Taking advantage of the fact that null values are not included in aggregate functions, we can use a CASE statement to control the average, as in the following:
select avg(amt) as average,
avg(case when col=some_val then amt else null end) as conditionalAverage
from myTable;
Sample Demo: http://sqlize.com/2IXwbWD2Eb
There is another way, not using case when
select
avg(amt) as average,
avg(if(col=some_val,amt,null)) as conditionalAverage
from myTable