Big Query Multiple Rolling Count - count

I have these data
I want to do two rolling count:
Count by every (id,refund) by rolling. When it turns into different (id,refund) combination (even with the same id), it will start from 0
Count by every id by rolling.
I want the output to be as follow:
Can you help me to create the query?
I try this one but it fails...
SELECT
date,
id,
refund,
COUNT(CONCAT(id,refund)) OVER (PARTITION BY rn) AS count_id_refund,
COUNT(id) OVER (PARTITION BY rn) AS count_id
FROM table1

You can use row_number() function. Here is my query with some sample data
with sample as (
select 1 as id, TRUE as refund,
union all select 1, true
union all select 1, false
union all select 2,true
union all select 3,true
union all select 3, false
union all select 3, false
)
select id,refund,
row_number() over(partition by id order by id) as row_id,
row_number() over(partition by concat(id,refund) order by concat(id,refund)) as row_id_rf
from sample order by id,refund desc;
and the result is:

Related

unique one column adn return all data with mariaDB [duplicate]

My database structure contains columns: id, name, value, dealer. I want to retrieve row with lowest value for each dealer. I've been trying to mess up with MIN() and GROUP BY, still - no solution.
Solution1:
SELECT t1.* FROM your_table t1
JOIN (
SELECT MIN(value) AS min_value, dealer
FROM your_table
GROUP BY dealer
) AS t2 ON t1.dealer = t2.dealer AND t1.value = t2.min_value
Solution2 (recommended, much faster than solution1):
SELECT t1.* FROM your_table t1
LEFT JOIN your_table t2
ON t1.dealer = t2.dealer AND t1.value > t2.value
WHERE t2.value IS NULL
This problem is very famous, so there is a special page for this in Mysql's manual.
Check this: Rows Holding the Group-wise Maximum/Minimum of a Certain Column
select id,name,MIN(value) as pkvalue,dealer from TABLENAME
group by id,name,dealer;
here you group all rows by id,name,dealer and then you will get min value as pkvalue.
SELECT MIN(value),dealer FROM table_name GROUP BY dealer;
First you need to resolve the lowest value for each dealer, and then retrieve rows having that value for a particular dealer. I would do this that way:
SELECT a.*
FROM your_table AS a
JOIN (SELECT dealer,
Min(value) AS m
FROM your_table
GROUP BY dealer) AS b
ON ( a.dealer= b.dealer
AND a.value = b.m )
Try following:
SELECT dealer, MIN(value) as "Lowest value"
FROM value
GROUP BY dealer;
select id, name, value, dealer from yourtable where dealer
in(select min(dealer) from yourtable group by name, value)
These answers seem to miss the edge case of having multiple minimum values for a dealer and only wanting to return one row.
If you want to only want one value for each dealer you can use row_number partition - group - the table by dealer then order the data by value and id. we have to make the assumption that you will want the row with the smallest id.
SELECT ord_tbl.id,
ord_tbl.name,
ord_tbl.value,
ord_tbl.dealer
FROM (SELECT your_table.*,
ROW_NUMBER() over (PARTITION BY dealer ORDER BY value ASC, ID ASC)
FROM your_table
) AS ord_tbl
WHERE ord_tbl.ROW_NUMBER = 1;
Be careful though that value, id and dealer are indexed. If not this will do a full table scan and can get pretty slow...

How to write one better sql of below two statements to improve the performance

If more than one ID for a match select id with max(date) .
if more than one id for above max dates select max(ID)
Go to TABLE1 to get high-dated IDS
Step 1 : identifying IDs which are having max dates
CREATE MULTISET VOLATILE TABLE TEST_VT
AS
(
SELECT
TABLE1.ID ,
TABLE1.KEY1,
TABLE1.STRT_DT,
TABLE1.TERM_DT,
Rank() OVER (PARTITION BY TABLE1.KEY1 ORDER BY TABLE1.STRT_DT DESC , TABLE1.ID DESC) RNK
FROM TABLE2
INNER JOIN TABLE1
ON TABLE2.KEY1=TABLE1.KEY1
WHERE TABLE1.TERM_DT='8888-12-31'
QUALIFY RNK=1
GROUP BY
1,2,3,4
)
WITH DATA PRIMARY INDEX(ID,KEY1) ON COMMIT PRESERVE ROWS;
Go to TABLE1 to get high-dated KEY1S associated with IDS from ABOVE STEP
Step 2 : If there is more than one max date take max ID out of all matched records in above step
SELECT
TABLE1.ID ,
TABLE1.KEY1,
TABLE1.STRT_DT,
TABLE1.TERM_DT,
RANK() OVER (PARTITION BY TABLE1.KEY1 ORDER BY TABLE1.STRT_DT DESC , TABLE1.ID DESC) AS RNK
FROM TABLE1
INNER JOIN TEST_VT
ON TEST_VT.ID=TABLE1.ID
INNER JOIN TABLE3
ON TABLE3.KEY1=TABLE1.KEY1
WHERE TABLE1.TERM_DT='8888-12-31'
QUALIFY RNK=1
GROUP BY
1,2,3,4

plsql count by date and sum up to the date

I'd like to have a plsql request that count the number of row by date and the sum of row up to the date.
The source will be somethings like this (hundreds of dates):
2019.05.01
2019.05.01
2019.05.02
2019.05.03
2019.05.03
2019.05.03
...
and the result:
date nb sum
-------------------
2019.05.01 2 2
2019.05.02 1 3
2019.05.03 3 6
. . .
The key here is to use an Aggregate Function as an Analytical function which is what the SUM(COUNT(dt)) OVER (ORDER BY dt) in the query below is doing.
WITH dates AS
(
SELECT to_date('2019.05.01', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.01', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.02', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual UNION ALL
SELECT to_date('2019.05.03', 'YYYY.MM.DD') AS dt FROM dual
)
SELECT dt, COUNT(dt) AS nb, SUM(COUNT(dt)) OVER (ORDER BY dt) AS sum
FROM dates
GROUP BY dt
;
First half is relatively easy. Something like
SELECT date, count(*) from table GROUP BY date ORDER BY date;
But I'm not sure about the cumulative sum. If it's a manual process then I'd probably just import into Excel and do it there to be honest.

Using more than one field with IN ( ) for a sub-query

In Google BigQuery, I would have to do something like:
SELECT hits.item.productName
FROM [‘Dataset Name’ ]
WHERE date, visitId, fullVisitorId IN (
SELECT date, visitId, fullVisitorId
FROM [‘Dataset Name’ ]
WHERE hits.item.productName CONTAINS 'Product Item Name A'
AND totals.transactions>=1)
However, this does not seem to be supported. What alternatives do I have besides using a JOIN?
Do a JOIN instead.
The equivalent of:
SELECT COUNT(*), stn, a.wban, FIRST(name) name, FIRST(country) country
FROM [fh-bigquery:weather_gsod.gsod2014] a
WHERE stn, wban IN
(SELECT usaf, wban FROM [fh-bigquery:weather_gsod.stations] WHERE country='UK')
GROUP BY 2, 3
ORDER BY 1 DESC
Would be:
SELECT COUNT(*), stn, a.wban, FIRST(name) name, FIRST(country) country
FROM [fh-bigquery:weather_gsod.gsod2014] a
JOIN [fh-bigquery:weather_gsod.stations] b
ON a.stn=b.usaf AND a.wban=b.wban
WHERE country='UK'
GROUP BY 2, 3
ORDER BY 1 DESC

How to remove null value form multiple column in sql select statement result set

How to achieve the result set in sql query
You could work along
WITH
T1 AS (
SELECT
val,
ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY id) rn
FROM Table1
),
T2 AS (
SELECT
val,
ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY id) rn
FROM Table2
),
T3 AS (
SELECT
val,
ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY id) rn
FROM Table3
)
SELECT
T1.val column1
, T2.val column2
, T3.val column3
FROM T1
JOIN T2
ON T1.rn = T2.rn
JOIN T3
ON T2.rn = T3.rn
ORDER BY T1.rn
;
You'd need to
put the statements, which are now going into the UNION into "T1" through "T3", and
move your current sort orders to the ROW_NUMBER analytic functions respectively.
… and should be done: SQL Fiddle
Please comment, if and as further detail is required.

Resources