Cannot use Count(*) in Lag() - mysql

I have a simple query but it keeps throwing "Invalid use of group function". It works fine when I remove "count(*)". How can I get the count without using it in lag?
select CreateDate as date, count(*) as count,
lag(count(*), 1) over(order by CreateDate) as previous
from contacts
group by createdate

Hmmm . . . MySQL should allow the use of aggregation functions with window functions. Maybe there is a bug in the parser though.
I think this will work:
select d.*, lag(cnt) over (order by cnt) as previous
from (select CreateDate as date, count(*) as cnt
from contacts
group by CreateDate
) d;

Related

How to filter out results on the basis of odd and even row number using window functions, no existing column as Row ID

I am currently using the following code, but it is not working, Please guide me-
select name, Continent, LifeExpectancy
from world.country
where mod(Row_Number()
over(order by Continent),2)=0;
You typically would need a subquery here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY Continent) rn
FROM world.country
)
SELECT name, Continent, LifeExpectancy
FROM cte
WHERE rn % 2 = 0; -- for evens
You can make a subquery to use the WINDOW funtion.
Can you pls try this ?
select name, Continent
from (
select name, Continent, LifeExpectancy, Row_Number() over(order by Continent) rn
from world.country) rs
where mod(rs.rn,2)=0;

How to get total number of records sql daily

I am currently doing to get the count,
Select count(*) from MyTable WHERE ATTEMPT_DATE='01/JUNE/19';
Select count(*) from MyTable WHERE ATTEMPT_DATE='02/JUNE/19';
.
.
Select count(*) from MyTable WHERE ATTEMPT_DATE='30/JUNE/19';
Is there any way to get all the SUM of ( count(*) all dates)
You can use aggregation:
select ATTEMPT_DATE, count(*)
from MyTable
group by ATTEMPT_DATE;
If you want to counts dates within a range, use where:
select count(*)
from MyTable
where ATTEMPT_DATE in ('01/JUNE/19', . . . '30/JUNE/19');
You are using a non-standard date format. If this were a standard date format (or if the column really is a date/datetime value), then I would suggest inequalities rather than in.
Why don't you use direct count(*)
Select count(*) from MyTable WHERE ATTEMPT_DATE BETWEEN '01/JUNE/19' AND '30/JUNE/19'
for datewise count use group by
Select ATTEMPT_DATE, count(*) from MyTable
WHERE ATTEMPT_DATE BETWEEN '01/JUNE/19' AND '30/JUNE/19' group by ATTEMPT_DATE
Cheers!!

Presto equivalent for Redshift's PERCENTILE_DISC

Given a query below in Redshift:
select
distinct cast(joinstart_ev_timestamp as date) as session_date,
PERCENTILE_DISC(0.02) WITHIN GROUP (ORDER BY join_time) over(partition by
trunc(joinstart_ev_timestamp))/1000 as mini,
median(join_time) over(partition by trunc(joinstart_ev_timestamp))/1000 as jt,
product_name as product,
endpoint as endpoint
from qe_datawarehouse.join_session_fact
where
cast(joinstart_ev_timestamp as date) between date '2018-01-18' and date '2018-01-30'
and lower(product_name) LIKE 'gotoTest%'
and join_time > 0 and join_time <= 600000 and join_time is not null
and audio_connect_time >= 0
and (entrypoint_access_time >= 0 or entrypoint_access_time is null)
and (panel_connect_time >= 0 or panel_connect_time is null) and version = 'V2'
I need to convert above Query to corresponding Presto syntax.
Corresponding Presto query I wrote is:
select
distinct cast(joinstart_ev_timestamp as date) as session_date,
PERCENTILE_DISC( WITHIN GROUP (ORDER BY cast(join_time as double))
over(partition by cast(joinstart_ev_timestamp as date) )/1000 as mini,
approx_percentile(cast(join_time as double),0.50) over (partition by
cast(joinstart_ev_timestamp as date)) /1000 as jt,
product_name as product,
endpoint as endpoint
from datawarehouse.join_session_fact
where
cast(joinstart_ev_timestamp as date) between date '2018-01-18' and date '2018-01-30'
and lower(product_name) LIKE 'gotoTest%'
and join_time > 0 and join_time <= 600000 and join_time is not null
and audio_connect_time >= 0
and (entrypoint_access_time >= 0 or entrypoint_access_time is null)
and (panel_connect_time >= 0 or panel_connect_time is null) and version = 'V2'
Here, everything is working fine but it is showing error in the line:
PERCENTILE_DISC( WITHIN GROUP (ORDER BY cast(join_time as double))
over(partition by cast(joinstart_ev_timestamp as date) )/1000 as mini,
What will be its corresponding Presto Syntax?
If Presto supported nested window functions then you could use NTH_VALUE along with p*COUNT(*) OVER (PARTITION BY ...) to find the offset corresponding to the "p'th" percentile in the window. Since Presto doesn't support this, you need to join to a subquery that calculates the number of records in the window instead:
SELECT
my_table.window_column,
/* Replace :p with the desired percentile (in your case, 0.02) */
NTH_VALUE(:p*subquery.records_in_window, my_table.ordered_column)
OVER (PARTITION BY my_table.window_column ORDER BY my_table.ordered_column BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM my_table
JOIN (
SELECT
window_column,
COUNT(*) AS records_in_window
FROM my_table
GROUP BY window_column
) subquery ON subquery.window_column = my_table.window_column
The above is conceptually close but fails because :p*subquery.records_in_window is a float and the offset needs to be an integer. You have a few options for how to deal with this this. For example, if you're finding the median then simply rounding to the nearest integer works. If you're finding the 2nd percentile, rounding won't work because it will often give you 0 and the offset starts at 1. In that case, rounding the ceiling to the nearest integer might be better.
I was doing some research on median in presto, and found a solution that worked for me:
For example, I had a join table, A_join_B, that has columns A_id and B_id.
I wanted to find median of number of A related to a single B
SELECT APPPROX_PERCENTILE(count, 0.5)
FROM
(
SELECT COUNT(*) AS count, narrative_id
FROM A_join_B
GROUP BY B_id
) as counts;

MySQL query to SQL-Server

I have a mysql query that I have to convert to sql server syntax, I am novice and perhaps someone can help me. Here is my code:
SELECT id, nick, mobile, name, description, direction, date, image FROM mytable WHERE number=1 ORDER BY date desc LIMIT 1, 10;
Is there some tool to try sql server querys or some online converter
Thanks for all
For SQL 2012, you have the rather unwieldy syntax:
SELECT id, nick, mobile, name, description, direction, date, image
FROM mytable WHERE number=1
ORDER BY date desc
OFFSET 100 ROWS FETCH NEXT 5 ROWS ONLY;
For SQL 2005, you generally need to adopt a 2-step approach to pagination via a derived table, e.g.
SELECT *
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY date desc) As RowID,
id, nick, mobile, name, description, direction, date, image
FROM mytable
WHERE number=1
) As RowResults
WHERE RowID BETWEEN 101 AND 106;
SqlFiddle here
UPDATED :
select * FROM
(
select ROW_NUMBER() OVER (ORDER BY ID) as RowNumber , * FROM mytable
) tmp
where tmp.RowNumber between 15 AND 30

sql calculate change and percent by year

I have an data set that simulates the rate of return for a trading account. There is an entry for each day showing the balance and the open equity. I want to calculate the yearly, or quarterly, or monthly change and percent gain or loss. I have this working for daily data, but for some reason I can't seem to get it to work for yearly data.
The code for daily data follows:
SELECT b.`Date`, b.Open_Equity, delta,
concat(round(delta_p*100,4),'%') as delta_p
FROM (SELECT *,
(Open_Equity - #pequity) as delta,
(Open_Equity - #pequity)/#pequity as delta_p,
(#pequity:= Open_Equity)
FROM tim_account_history p
CROSS JOIN
(SELECT #pequity:= NULL
FROM tim_account_history
ORDER by `Date` LIMIT 1) as a
ORDER BY `Date`) as b
ORDER by `Date` ASC
Grouping by YEAR(Date) doesn't seem to make the desired difference. I have tried everything I can think of, but it still seems to return daily rate of change even if you group by month or year, etc. I think I'm not using windowing correctly, but I can't seem to figure it out. If anyone knows of a good book about this sort of query I'd appreciate that also.
Thanks.sqlfiddle example
Using what Lolo contributed, I have added some code so the data comes from the last day of the year, instead of the first. I also just need the Open_Equity, not the sum.
I'm still not certain I understand why this works, but it does give me what I was looking for. Using another select statement as a from seems to be the key here; I don't think I would have come up with this without Lolo's help. Thank you.
SELECT b.`yyyy`, b.Open_Equity,
concat('$',round(delta, 2)) as delta,
concat(round(delta_p*100,4),'%') as delta_p
FROM (SELECT *,
(Open_Equity - #pequity) as delta,
(Open_Equity - #pequity)/#pequity as delta_p,
(#pequity:= Open_Equity)
FROM (SELECT (EXTRACT(YEAR FROM `Date`)) as `yyyy`,
(SUBSTRING_INDEX(GROUP_CONCAT(CAST(`Open_Equity` AS CHAR) ORDER BY `Date` DESC), ',', 1 )) AS `Open_Equity`
FROM tim_account_history GROUP BY `yyyy` ORDER BY `yyyy` DESC) p
CROSS JOIN
(SELECT #pequity:= NULL) as a
ORDER BY `yyyy` ) as b
ORDER by `yyyy` ASC
Try this:
SELECT b.`Date`, b.Open_Equity, delta,
concat(round(delta_p*100,4),'%') as delta_p
FROM (SELECT *,
(Open_Equity - #pequity) as delta,
(Open_Equity - #pequity)/#pequity as delta_p,
(#pequity:= Open_Equity)
FROM (SELECT YEAR(`Date`) `Date`, SUM(Open_Equity) Open_Equity FROM tim_account_history GROUP BY YEAR(`Date`)) p
CROSS JOIN
(SELECT #pequity:= NULL) as a
ORDER BY `Date` ) as b
ORDER by `Date` ASC