Division in group by SQL table - sql

I have the following SQL code
SELECT (COUNT(*) filter (WHERE has_a)) AS count_a,
COUNT(*) AS total_count,
process_date
FROM(SELECT process_date::date AS process_date,
(CASE WHEN (columnA > 0) THEN true ELSE false END) AS has_a
FROM my_table)
temptable
GROUP BY process_date
LIMIT 5;
which gives the following table
I want to create a column called percent_a with value (count_a/total_count)*100 grouped by process_date. E.g for row 1 the new column would have value 49.4 i.e. (1030/2085)*100.
I have tried
SELECT process_date,
((COUNT(*) filter (WHERE has_a))/COUNT(*) * 100) AS percent_a,
FROM(SELECT process_date::date AS process_date,
(CASE WHEN (columnA > 0) THEN true ELSE false END) AS has_a,
FROM my_table)
temptable
GROUP BY process_date
ORDER BY process_date DESC
LIMIT 1;
But this just gave 0s.
How can I create the column to display the % I want? I think something is happening with the GROUP BY but I don't know how to fix it.

It's because count returns an integer, you just need to cast it:
SELECT process_date,
(((COUNT(*) filter (WHERE has_balance))::DOUBLE PRECISION)/COUNT(*) * 100) AS percent_a,
FROM(SELECT process_date::date AS process_date,
(CASE WHEN (columnA > 0) THEN true ELSE false END) AS has_a,
FROM my_table)
temptable
GROUP BY process_date
ORDER BY process_date DESC
LIMIT 1;

Related

Invalid Column Name Error when using Sum Case function in SQL

I am trying to sum all case where the field name [Unique] is > 1. I am using Sum case statement and the column [Unique] is not picking up, I also tried to paste the code of unique in and that did not work.
SELECT DSID, SRC_START_DTTM, SRC_END_DTTM
, DWID + CONVERT(float, FORMAT(SRC_END_DTTM, N'yyyyMMddHH'))/10000000000 AS [~Project]
,
ROW_NUMBER()
OVER (
PARTITION BY DWID + CONVERT(float, FORMAT(SRC_END_DTTM, N'yyyyMMddHH'))/10000000000
ORDER BY SRC_END_DTTM DESC, SRC_START_DTTM DESC
) AS [UNIQUE],
SUM(
CASE
WHEN [UNIQUE] > 1 THEN 1
ELSE 0
END) as Test
FROM F.DIM
GROUP BY DSID, SRC_START_DTTM, SRC_END_DTTM, DWID
ORDER BY [UNIQUE] DESC
ERROR: Invalid Column Name 'Unique'
You are trying to use aliased name of a column in same query which is not possible
Try below
SELECT
T.DSID, T.SRC_START_DTTM, T.SRC_END_DTTM, T.DWID
,SUM(
CASE
WHEN T.[UNIQUE] > 1 THEN 1
ELSE 0
END) as Test
FROM
(SELECT DSID, SRC_START_DTTM, SRC_END_DTTM
, DWID + CONVERT(float, FORMAT(SRC_END_DTTM, N'yyyyMMddHH'))/10000000000 AS [~Project]
, ROW_NUMBER()
OVER (
PARTITION BY DWID + CONVERT(float, FORMAT(SRC_END_DTTM, N'yyyyMMddHH'))/10000000000
ORDER BY SRC_END_DTTM DESC, SRC_START_DTTM DESC
) AS [UNIQUE]
FROM F.DIM) AS T
GROUP BY T.DSID, T.SRC_START_DTTM, T.SRC_END_DTTM, T.DWID
ORDER BY T.[UNIQUE] DESC

SQL for begin and end of data rows

I've got the following table:
and I was wondering if there is an SQL query, which would give me the begin and end Calender week (CW), where the value is greater than 0.
So in the case of the table above, a result like below:
Thanks in advance!
You can assign a group by counting the number of zeros and then aggregating:
select article_nr, min(year), max(year)
from (select t.*,
sum(case when amount = 0 then 1 else 0 end) over (partition by article_nr order by year) as grp
from t
) t
where amount > 0
group by article_nr, grp;
select Atricle_Nr, min(Year&CW) as 'Begin(Year&CW)',max(Year&CW) as 'End(Year&CW)'
from table where Amount>0 group by Atricle_Nr;

calculate percentage of null values based on group by

I'm trying to modify this solution (the first answer) that counts null values based on group by, the only difference is I want percentage of them (e.g. 30% of the column1 for year 2016 is null), not count (e.g. 6521 of th column1 for year 2016 is null). My query:
WITH t1nulltest AS
( select date_column
,SUM(IF(c1 IS NULL,1,0))/count(*) OVER (PARTITION BY date_column) as c1null
,SUM(IF(c2 IS NULL,1,0))/count(*) OVER (PARTITION BY date_column) as c2null
,SUM(IF(c3 IS NULL,1,0))/count(*) OVER (PARTITION BY date_column) as c3null
,SUM(IF(c4 IS NULL,1,0))/count(*) OVER (PARTITION BY date_column) as c4null
,SUM(IF(c5 IS NULL,1,0))/count(*) OVER (PARTITION BY date_column) as c5null
,row_number() OVER (PARTITION BY date_column) as rowno
from t1)
select
date_column, c1null, c2null,c3null,c4null,c5null from t1nulltest
where rowno =1;
The only difference from the original solution is that I add /count(*), but this doesn't work, and I wonder why. The original query works. My query gives the error:
Error while compiling statement: FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns. Also check for circular dependencies. Underlying error: org.apache.hadoop.hive.ql.parse.SemanticException: line 2:68 Expression not in GROUP BY key 'date_column'
I suspect that the whole logic can be simplified into a simple aggregation query.
select
date_column,
1.0 * (count(*) - count(c1)) / count(*) c1_null_ratio,
1.0 * (count(*) - count(c2)) / count(*) c2_null_ratio,
1.0 * (count(*) - count(c3)) / count(*) c3_null_ratio,
1.0 * (count(*) - count(c4)) / count(*) c4_null_ratio,
1.0 * (count(*) - count(c5)) / count(*) c5_null_ratio
from t1
group by date_column
This can also be phrased with avg():
select
date_column,
avg(case when c1 is null then 1 else 0 end) c1_null_ratio,
avg(case when c2 is null then 1 else 0 end) c2_null_ratio,
avg(case when c3 is null then 1 else 0 end) c3_null_ratio,
avg(case when c4 is null then 1 else 0 end) c4_null_ratio,
avg(case when c5 is null then 1 else 0 end) c5_null_ratio,
from t1
group by date_column

How to make Ranking using case by Partition in SQL Server?

I need to do Ranking, if the value is negative, then sort it by Asc, if it is positive then sort it by Desc
select
Itemcode,
isnull(sum(ss.DiscQty * ss.Cost),0) DescCost,
RANK()OVER(Partition by Itemcode order by
case when isnull(sum(ss.DiscQty * ss.Cost),0) < 0 THEN isnull(sum(ss.DiscrepancyQty * ss.Cost),0) END ASC,
case when isnull(sum(ss.DiscQty * ss.Cost),0) > 0 THEN isnull(sum(ss.DiscQty * ss.Cost),0) END DESC
) RANKS
from
ss
Group by
ItemNo
Is this the pattern you are after?
Have simplified the code to highlight what is happening
;WITH Example (n) AS
(
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT -1 UNION ALL
SELECT -2 UNION ALL
SELECT -3
)
SELECT n
,ROW_NUMBER() OVER (ORDER BY ABS(n)-0 DESC)
FROM Example
ORDER BY n,ROW_NUMBER() OVER (ORDER BY ABS(n)-0 DESC)
You cannot change the criteria dynamically. Do the following
SELECT
Brand,
ItemNo,
RANK() OVER (PARTITION BY ItemNo ORDER BY
CASE WHEN ISNULL(Disc, 0) > 0 THEN SUM(Quantity * Item.Cost) ELSE 0 END DESC,
CASE WHEN ISNULL(ST_ItemEntry.Discrepancy, 0) < 0 THEN SUM(Quantity * Item.Cost) ELSE 0 END ASC
) AS [Rank]
FROM
item
GROUP BY
Brand,ItemNo

SQL query min and max group by flag

I have a table as below :
How can I craft a SQL select statement so that MIN AND MAX EVENT DATE groups results by FLAG (0,1)?
So the result would be:
Just do conditional aggregation with use of window function
SELECT card_no, descr_reader,
max(CASE WHEN flag = 0 THEN event_date END) date_in,
max(CASE WHEN flag = 1 THEN event_date END) date_out
FROM
(
SELECT *,
COUNT(flag) OVER (PARTITION BY flag ORDER BY id) Seq
FROM table t
)t
GROUP BY card_no, descr_reader, Seq
An alternative if Window function does not work:
SELECT
t1.card_no, t1.descr_reader,
t1.event_date date_in,
(select top 1 event_date from test t2
where t2.card_no = t1.card_no and
t2.reader_no = t1.reader_no and
t2.descr_reader = t1.descr_reader and
t2.event_date > t1.event_date and
t2.flag = 1
order by t2.event_date ) as date_out
FROM test t1
WHERE t1.flag = 0