Bigquery - Calculate Quantity Added to Cart - google-analytics

Is there a way to calculate Quantity Added to Cart similar to the GA metric:
ga:quantityAddedToCart
UI Name: Quantity Added To Cart
Number of product units added to the shopping cart (Enhanced Ecommerce).
In the BQ Export schema, I only see these three things:
hits.product.productQuantity INTEGER: The quantity of the product purchased.
hits.item.itemQuantity INTEGER: The quantity of the product sold.
hits.eCommerceAction.action_type STRING: The action type. Click through of product lists = 1, Product detail views = 2, Add product(s) to cart = 3, Remove product(s) from cart = 4, Check out = 5, Completed purchase = 6, Refund of purchase = 7, Checkout options = 8, Unknown = 0.
The first two only talk about the quantity sold and I already tried to see if I could combine these two with hits.eCommerceAction.action_type = 3, but no luck as per below:
SELECT
date,
product.v2ProductName AS productListName,
CASE WHEN hits.eCommerceAction.action_type = '3' THEN item.itemQuantity ELSE 0
END AS quantityAddedToCart_method1,
CASE WHEN hits.eCommerceAction.action_type = '3' THEN product.productQuantity ELSE 0
END AS quantityAddedToCart_method2
FROM
`{PROJECT_ID}.{VIEW_ID}.ga_sessions_*`,
UNNEST(hits) hits,
UNNEST(hits.product) product
WHERE
_TABLE_SUFFIX BETWEEN '20190401' AND '20190430'

Related

How to create a conversion funnel based on pages and events for GA data in BigQuery

I have the following data in BigQuery:
date fullVisitorId sessionId hitNumber type url eventCategory eventAction eventLabel
20210101 973454546035798949 973454546035798949162783837520210101 1 PAGE homepage.com Null Null Null
20210101 973454546035798949 973454546035798949162783837520210101 2 EVENT homepage.com/purchase View Book Harry_Potter
20210101 973454546035798949 973454546035798949162783837520210101 3 EVENT homepage.com/purchase Purchase Book Harry_Potter
...
I want to create a conversion funnel based on URLs and events, not necessarily sequential. For example, I want to calculate the number of distinct users (fullVisitorId) and the number of distinct sessions (sessionId) in which:
Users visited the homepage (homepage.com).
Then the event with Category View, Action Book and Label Harry_Potter was triggered,
Then the event with Category Purchase, Action Book and Label Harry_Potter was triggered.
Again the hits are not necessarily sequential, which means that the hit numbers could be 1, 4, and 8, respectively, for these 3 steps. Also, the real number of desired steps is more than 10.
Ideally, the final results should look like this:
Type Date Step 1 Step 2 Step 3 Step 4
Users 01/01/2021 120 110 90 ...
Users 02/01/2021 130 80 70 ...
Sessions 01/01/2021 200 120 100 ...
Sessions 02/01/2021 220 80 70 ...
where Step 1, Step 2, and Step 3 represent the number of users and sessions in which the particular step was done.
Any ideas? Thanks!
You will have to do something like this, below SQL code. For every condition u can have a CTE and then join.
WITH STEP1 AS
(
SELECT fullVisitorId, Date, SUM(hitNumber) AS STEP1
FROM `data-to-insights.ecommerce.all_sessions_raw`
WHERE STARTS_WITH(url, "homepage.com") AND fullVisitorId IS NOT NULL
GROUP BY fullVisitorId, Date
),
STEP2 AS
(
SELECT fullVisitorId, Date, SUM(hitNumber) AS STEP2
FROM `data-to-insights.ecommerce.all_sessions_raw`
WHERE eventCategory = 'View' AND eventAction = 'Book' AND eventLabel = 'Harry_Potter' AND fullVisitorId IS NOT NULL
GROUP BY fullVisitorId, Date
),
STEP3 AS
(
SELECT fullVisitorId, Date, SUM(hitNumber) AS STEP3
FROM `data-to-insights.ecommerce.all_sessions_raw`
WHERE eventCategory = 'Purchase' AND eventAction = 'Book' AND eventLabel = 'Harry_Potter' AND fullVisitorId IS NOT NULL
GROUP BY fullVisitorId, Date
),
JOINED_DATA AS
(
SELECT 'Users' AS Type,
coalesce(SUB_QUERY.Date,STEP3.Date),
STEP1.STEP1,
STEP2.STEP2,
STEP3.STEP3
FROM STEP3 FULL OUTER JOIN
(
SELECT coalesce(STEP1.fullVisitorId,STEP2.fullVisitorId) AS fullVisitorId,
coalesce(STEP1.Date,STEP2.Date) AS Date
FROM STEP1 FULL OUTER JOIN STEP2
ON STEP1.DATE = STEP2.DATE AND STEP1.fullVisitorId = STEP2.fullVisitorId
) AS SUB_QUERY
ON STEP3.fullVisitorId = SUB_QUERY.fullVisitorId AND STEP3.Date = SUB_QUERY.Date
)
SELECT * FROM JOINED_DATA

Avg. product list position of added to cart product

I'd like to return the Avg. product list position of added to cart product. I'm using the googlemerchandisestore.com. The idea is to calculate the avg. product position of the Search Results product list for each product that has been added to cart during sessions.
So far I have the following query:
SELECT
visitId,
prods.productSKU AS SKU,
prods.v2ProductName AS Name,
prods.productListName AS ProductList,
AVG(prods.productListPosition) AS Average_Position
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`,
UNNEST(hits) hits,
UNNEST(hits.product) prods
WHERE
(_TABLE_SUFFIX BETWEEN '20170601'
AND '20170731') and prods.productListName = "Search Results"
GROUP BY
visitId,
SKU,
Name,
ProductList
ORDER BY
Average_Position ASC
This query return me the avg. product position of the Search Results product list for ALL the product. So I need to find a way to filters out product that as not been added to cart.
Couldn't test but maybe this helps you:
SELECT
sku,
name,
(SELECT AVG(position) FROM UNNEST(positions) AS position) AS avg_position
FROM(
SELECT
ARRAY(SELECT AS STRUCT
productSKU AS sku,
v2ProductName AS name,
ARRAY_AGG(IF(productListName='Search Results', productListPosition, NULL) IGNORE NULLS) AS positions,
MAX(IF(ecommerceAction.action_type='3', TRUE, NULL)) AS is_carted
FROM UNNEST(hits) LEFT JOIN UNNEST(product)
GROUP BY sku, name) AS hits
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
(_TABLE_SUFFIX BETWEEN '20170601' AND '20170631')
AND EXISTS(SELECT 1 FROM UNNEST(hits), UNNEST(product) WHERE productListName = 'Search Results')
AND EXISTS(SELECT 1 FROM UNNEST(hits) WHERE ecommerceaction.action_type = '3')
), UNNEST(hits)
WHERE is_carted
AND ARRAY_LENGTH(positions) > 0

Join 3 tables without losing ability to refer each table

I have 3 tables with this mock data
Item *id, name*
1, coke
2, fanta
3, juice
Branch *id, name*
1, store
2, warehouse
3, shop
BranchItem *item_id, branch_id, qty*
1, 1, 100
1, 2, 30
2, 2, 10
I want to query for an item(coke for example) and get its quantity in all branches( even the ones it doesn't exist in, those should have NULL for qty column)
So the result should look like
1, coke, store, 100
1, coke, warehouse, 30
1, coke, shop, NULL
I have a query that can do this, but because of aliasing tables, I lose the ability to refer to the column of the result table. The parsing of the result is done in an ORM object which preferably shouldn't be rewritten
The query I have
Select * from item left join (select * from branch left join ( select * from branchitem where item_id = 1) branchitem on branch.id = branchitem.branch_id) JOINEDNAME on true where item.id = 1;
My question is I don't want to Elias the join of branch and brunch item as I lose the ability to refer to them separately in the ORM. How can this query be re-written so the tables retain their names?
You don't need to use subqueries:
SELECT Item.id,
Item.name,
Branch.name,
BranchItem.qty
FROM Item
CROSS JOIN Branch
LEFT JOIN BranchItem ON Item.id = BranchItem.item_id
AND Branch.id = BranchItem.branch_id
WHERE Item.id = 1; -- or put it into the branch join

update Trigger gives invalid statement

I have this trigger in sqlite which is giving invalid statement error
I am trying to update the table orders after a payment has been inserted.
The trigger looks for all payment with the payments orderid, sums it, and update the total in the orders
payments table
Amount
ID
OrderID
Orders Table
ID
Paid
Bal
The trigger
CREATE TRIGGER [update_order_total]
AFTER INSERT
ON Payments
FOR EACH ROW
BEGIN
UPDATE Orders Set Orders.Paid =(Select SUM (Amount) From Payments Where OrderID = Orders.id ) WHere id = new.ID;
UPDATE Orders Set Orders.Bal = Orders.Paid - (Select SUM (Amount) From Payments Where OrderID = Orders.id ) WHere id = new.ID;
END
EDIT
I made edit to the trigger, the first statements now works, but the second update statement doesn't
CREATE TRIGGER [update_order_total]
AFTER INSERT
ON Payments
FOR EACH ROW
BEGIN
UPDATE Orders Set Paid =(Select SUM (Amount) From Payments AS p Where p.OrderID = Orders.ID) WHere Orders.id = new.ID;
UPDATE Orders Set Bal = Paid - (Select SUM (Amount) From Payments AS p Where p.OrderID = Orders.ID) WHere Orders.id = new.ID;
END
Please what am I doing wrong?
After hours of debugging, I finally solved myself with the following statement
CREATE TRIGGER [update_order_total]
AFTER INSERT
ON Payments
FOR EACH ROW
BEGIN
UPDATE Orders Set Paid =(Select SUM (Amount) From Payments AS p Where p.OrderID = Orders.ID),PayMethod =new.PayMethod WHere Orders.id = new.OrderID;
UPDATE Orders Set Bal = Total - (Select SUM (Amount) From Payments AS p Where p.OrderID = Orders.ID) WHere Orders.id = new.OrderID;
END
Regards

asp.net using pagination with repeater

I wanted to create pagination for my reapeater. In database I have posts. I want to display firstly logged in users posts and then the rest (for example 40 per site).
I wonder if there is a way to retreive from database rows form 40 to 80 or from 80 to 120.
Thanks for any hints.
Let's assume that your table has following columns: ID, UserID, PostedDate, Subject
Then query may look like the one below:
DECLARE #LoggedInUserID int,
#RowsPerPage int,
#PageNum int;
SELECT #LoggedInUserID = 1,
#RowsPerPage = 10,
#PageNum = 1;
with BlogPostCTE
AS
(
select
bp.ID,
bp.UserID,
bp.PostedDate,
CASE WHEN bp.UserID = #LoggedInUserID THEN 1 ELSE 0 END as IsLoggedInUser,
bp.[Subject]
from BlogPost as bp
), BlogPostWithPagingCTE
AS
(
Select Top(#RowsPerPage * #PageNum)
ResultNum = ROW_NUMBER() OVER (ORDER BY IsLoggedInUser desc, UserID, PostedDate asc),
ID,
UserID,
PostedDate,
IsLoggedInUser,
[Subject]
FROM BlogPostCTE
)
select
ID,
UserID,
PostedDate,
[Subject]
FROM BlogPostWithPagingCTE
where ResultNum > ((#PageNum - 1) * #RowsPerPage)

Resources