Not sure how to sure how to best phrase it, but essentially I need ~50 columns x 12 weeks in BigQuery and was hoping there was a way to do it more efficiently using some sort of logic or function.
I can generate the script in Python, but the end output itself is long and unwieldy. Is there a cleaner way to do it within BigQuery itself?
Example code:
select id,
sum(case when first_week_flag then visit else 0 end) as sum_visit_first_week,
sum(case when second_week_flag then visit else 0 end) as sum_visit_second_week,
... for 12 weeks,
avg(case when first_week_flag then gap else 0 end) as avg_gap_first_week,
avg(case when second_week_flag then gap else 0 end) as avg_gap_second_week,
... for 12 weeks,
etc. for 50 columns
from table
group by id
Potential for simplification:
select id,
sum(case when {WEEK}_flag then visit else 0 end) as sum_visit_{WEEK},
avg(case when {WEEK}_flag then gap else 0 end) as avg_gap_{WEEk},
etc. for 50 columns
from table
group by id
Can anyone point me in the right direction of what to search for? Thanks!
Related
I am new to SQL in general, hence this problem is a little tricky to me. I have a table like the example below:
Input Values:
And, I wish to get the following output:
Output Result:
Honestly, I have no idea how to begin to solve this problem. I would appreciate a hint and/or an example solution from anyone. Thank you in advance.
You can perform conditional aggregation and then use a ROLLUP.
For example:
select
velocity,
sum(case when volume = 'VERY HIGH' then sales else 0 end) as very_high,
sum(case when volume = 'HIGH' then sales else 0 end) as high,
sum(case when volume = 'MEDIUM-HIGH' then sales else 0 end) as medium_high,
sum(case when volume = 'LOW' then sales else 0 end) as low,
sum(case when volume = 'VERY LOW' then sales else 0 end) as very_low,
sum(sales) as total
from t
group by rollup (velocity)
order by velocity
I have a table A with the following transaction data:
ID Name Type
1 Albert Rewards
2 Albert Visit
3 Ruddy Rewards
4 Ruddy Visit
5 Ruddy Purchase
6 Mario Rewards
7 Mario Visit
...
I want a table that only select the rows with names of people who used the "Rewards" and "Visit" type but didn't make a purchase, something like this:
ID Name Type
1 Albert Rewards
2 Albert Visit
6 Mario Rewards
7 Mario Visit
...
Any ideas?
The below query will count for every Visit/Rewards/Purchase how often they happened for a given name - and if the respective results are 1/1/0 then all records from the table with that name will be returned.
If fine-tuning is required (such as cases where the count of any of those > 1 etc.) that can be done by fiddling with the numbers in the 'having' clause. The same is true for adding additional categories to check against.
select *
from mytable a
where exists (select b.name,
sum(case when b.type='Rewards' then 1 else 0 end),
sum(case when b.type='Visit' then 1 else 0 end),
sum(case when b.type='Purchase' then 1 else 0 end)
from mytable b
where b.name=a.name
group by b.name
having sum(case when b.type='Rewards' then 1 else 0 end) = 1
and
sum(case when b.type='Visit' then 1 else 0 end) = 1
and
sum(case when b.type='Purchase' then 1 else 0 end) = 0);
For completion sake: SQLFiddle with 2 queries First query also works, but a little differently
I have a requirement to group data in transaction table into 4 week groups, or accounting month grouping, any suggestions on how to approach it on postgresql
Regards
SELECT sum(ITEM_C._demand) AS aggre_demand,ITEM_C._week as account_month FROM (SELECT sum(quantity) AS _demand,( CASE WHEN floor((extract(doy from shipment_date)-1)/7)+1 > 0 AND floor((extract(doy from shipment_date)-1)/7)+1 <=4 THEN 1
ELSE (CASE WHEN floor((extract(doy from shipment_date)-1)/7)+1 >4 AND floor((extract(doy from shipment_date)-1)/7)+1 <=8 THEN 2 ELSE 3 END ) END)AS _week, date_trunc('year',shipment_date) AS _Year
FROM smp.shipment
GROUP BY floor((extract(doy from shipment_date)-1)/7)+1,date_trunc('year',shipment_date)) AS ITEM_C
GROUP BY ITEM_C._week, ITEM_C._Year
I think this is not the idle way to do this, as i need to repeat this 1..52 weeks total 13 times
use date_trunc
https://www.postgresql.org/docs/9.1/static/functions-datetime.html
Anything more than this will need some more information. copy some examples and anything you have tried already.
SELECT date_trunc('week', your_date_field)
FROM your_table_name
GROUP BY 1
This query works in data studio, but fails to show alias in MS Query!
I have tried different types such as "",'',[] and even https://support.microsoft.com/en-us/kb/298955
SELECT 'TRANIN'AS NAME, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601 THEN 1 else 0 END) AS CurrentMonth, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531 THEN 1 else 0 END) AS LastMonth
FROM ALT3
MS broke MS query a long time ago...
I've tried to get it to work right, but nothing worked. I've pretty much given up.
Normally I just rename the column once the data is back in Excel.
But if you really want the name returned from MS query, this works:
WITH tbl AS (SELECT 'TRANIN'AS NAME
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601
THEN 1 else 0 END) AS CurrentMonth
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531
THEN 1 else 0 END) AS LastMonth
FROM ALT3)
SELECT * FROM TBL
Good Day Everyone!
well i have this kind of code and it kinda ugly,
a friend of mine told me i can implement Case Statements in here, but i do not know how or how would i implement, the code is long so if you could just help me to optimize my code i would appreciate it greatly!
PS. please be gentle to me, im new in T-sql :)
Thank yoU!
SELECT
SUM(CYJEWELRY) 'CY_Jewelry'
,SUM(CYAPPLICANCE) 'CY_Appliance'
,SUM(CYCELLPHONE) 'CY_Cellphone'
,SUM(PYJEWELRY) 'PY_Jewelry'
,SUM(PYAPPLIANCE) 'PY_Appliance'
,SUM(PYCELLPHONE) 'PY_Cellphone'
FROM
(
---TOTAL NUNG A FORMAT 0,0,0,0,0,0
--------------CURRENT YEAR JEWELRY
SELECT COUNT (*) AS CYJEWELRY,0 AS CYAPPLICANCE,0 AS CYCELLPHONE,0 AS PYJEWELRY,0 AS PYAPPLIANCE,0 AS PYCELLPHONE
FROM #TEMPTABLE1
WHERE (fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14)
UNION
-----------CURRENT YEAR APPLIANCE
SELECT 0,COUNT(*),0,0,0,0
FROM #TEMPTABLE1
WHERE fld_StorageGroupID = 1
UNION
------------CURRENT YEAR CELLPHONE
SELECT 0,0,COUNT(*),0,0,0
FROM #TEMPTABLE1
WHERE fld_StorageGroupID = 2
UNION
---------------LAST YEAR JEWELRY
SELECT 0,0,0,COUNT(*),0,0
FROM #TEMPTABLE2
WHERE (fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14)
UNION
-----------------------LAST YEAR APPLIANCE
SELECT 0,0,0,0,COUNT (*),0
FROM #TEMPTABLE2
WHERE fld_StorageGroupID = 1
UNION
-------------------------LAST YEAR CELLPHONE
SELECT 0,0,0,0,0,COUNT(*)
FROM #TEMPTABLE2
WHERE fld_StorageGroupID = 2
)A
Assuming your data is bit like this Sql Fiddle Example, try this for the sub query using SUM() and CASE.
SELECT SUM(CASE WHEN fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14 ELSE 0 END) Col1And4,
SUM(CASE WHEN fld_StorageGroupID = 1 THEN 1 ELSE 0 END) Col2And5,
SUM(CASE WHEN fld_StorageGroupID = 2 THEN 1 ELSE 0 END) Col3And6
FROM #TEMPTABLE1
GROUP BY fld_StorageGroupID
Since you are applying the same filter for last 3 columns in the subquery, I have done only first 3 columns here.
EDIT:
I think this is better than above (Note: no need to use SUM() in the main query).
Fiddle Example with data
select col1_4 CY_Jewelry,
col2_5 CY_Appliance,
col3_6 CY_Cellphone,
col1_4 PY_Jewelry,
col2_5 PY_Appliance,
col3_6 PY_Cellphone
from (
select sum(case when id>= 3 and id <= 14 then 1 else 0 end) col1_4,
sum(case when id = 2 then 1 else 0 end) col2_5,
sum(case when id = 3 then 1 else 0 end) col3_6
from t
--group by id
) X