Use 2 keys in a query - sql

I have in where event_params.key = 'page_referrer'
but, i want to see in select values event_params.key = 'traffic_type'
I need both fields
I wanted to use JOIN tables with itself, but didn't work out

Would you try below ?
SELECT (SELECT value.string_value FROM t.event_params WHERE key = 'traffic_type') traffic_type
FROM `coolclever-1148.analytic_xxxxxx.events_20230130` t
WHERE event_name = 'view_item' AND 'page_referrer' IN UNNEST(event_params.key);
Example Query
To show you working example with public dataset:
SELECT (SELECT value.string_value FROM t.event_params WHERE key = 'page_location') page_location
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` t
WHERE event_name = 'page_view' AND 'page_title' IN UNNEST(event_params.key);
Query results

Related

Update ARRAY IN ARRAY BigQuery (GA4 Data)

I want to update a value in array with a value in another table.
table1:
event_params.key
event_params.value.string_value
country
US
table2:
country
new_country
US
NL
I try
UPDATE table1
SET event_params = ARRAY(SELECT AS STRUCT * REPLACE ( new_country AS value.string_value ) FROM UNNEST(event_params)
WHERE key = "country")
FROM(SELECT country, new_country FROM table2)
WHERE
(SELECT value.string_value from unnest(event_params) where key = 'country') = t2.country
It doesnt work.. The problem is the value.string_value because is also an array.
The final table should look like
table1:
event_params.key
event_params.value.string_value
country
NL
Now I want to update table1 with table2 to udate the country from US to NL in table1.
How can I take the array in array?
I also saw this code:
UPDATE `project.dataset.your_table` t
SET hits =
ARRAY(
SELECT AS STRUCT * REPLACE(
ARRAY(
SELECT AS STRUCT product.* REPLACE(
CASE WHEN map.raw_name = product.productCategory THEN category
ELSE productCategoryAttribute END AS productCategoryAttribute)
FROM UNNEST(product) product
LEFT JOIN UNNEST(agg_map.map) map
ON map.raw_name = product.productCategory
) AS product)
FROM UNNEST(hits) hit
)
FROM (SELECT ARRAY_AGG(row) map FROM `project.dataset.map` row) agg_map
WHERE TRUE
BigQuery UPDATE nested array field
But I cant implement it.

Table name missing dataset after UNNEST event_params

I'm trying to execute the following query:
SELECT
(SELECT ep.value FROM ep
WHERE ep.key = 'key_name') AS key_name
FROM analytics_tables.events_20210824 e CROSS JOIN
UNNEST(event_params) AS ep
WHERE e.event_name = 'item_clicked' AND
ep.key = 'my_key_type' and ep.value.int_value=7;
But I'm getting this error message:
Table name "ep" missing dataset while no default dataset is set in the request
How should I reference "ep" in order for it to work?
Try below
SELECT
(SELECT value FROM e.event_params
WHERE key = 'key_name') AS key_name
FROM analytics_tables.events_20210824 e CROSS JOIN
UNNEST(event_params) AS ep
WHERE e.event_name = 'item_clicked' AND
ep.key = 'my_key_type' and ep.value.int_value=7;
You should set your database first before handling the table, otherwise it won't know to which database extract the data from.
USE database;
This solution has been extracted from the following quickstart.

Conditional IN Statement to be used inside Postgres function

I am working on Postgres and I have two tables vehicles and vehicles_flag. There are no relations between the two tables and hence we can not join two tables to fetch the required data.
The table structure is below (vehicle_flag table may not contain all the id present in the vehicle table) :
[Table structure]
I am writing a function that will accept multiple input parameters. I have to select vehicle id from the vehicle_flag table only if the flag value is true: otherwise, I have to ignore the vehicel_flag table. My aim is to achieve something like this, but turns out the case statement expects scaler output:
select count(id) from vehicles
where
vehicles.id in (case
when #hasbluetooth =1 then (select distinct id from vehicle_flags where flag='bluetooth' and value = '1')
else
(select distinct id from vehicles)
end)
and
vehicles.id in (case
when #hasac =1 then (select distinct id from vehicle_flags where flag='ac' and value = '1')
else
(select distinct id from vehicles)
end)
Kindly suggest any solution to achieve this.
I suspect you want:
select v.*
from vehicle v
left join vehicle_flags vf on vf.id = v.id
group by v.id
having
(#hasbluetooth = 0 or bool_or(vf.flag = 'bluetooth' and vf.value = 1)
and (#hasac = 0 or bool_or(vf.flag = 'ac' and vf.value = 1)

sql query for multi valued attributes

I have resources each represented by a guid and they have attribute name-value pairs. I would like to query
for resources which have the given attribute name value pairs.
So, suppose the table looks like:
GUID ATTR_SUBTYPE ATTR_VAL
63707829116544a38c5a508fcde031a4 location US
63707829116544a38c5a508fcde031a4 owner himanshu
44d5bf579d9f4b9a8c41429d08fc51de password welcome1
44d5bf579d9f4b9a8c41429d08fc51de host retailHost
c67d8f5d1a9b41428f029d55b79263e1 key random
c67d8f5d1a9b41428f029d55b79263e1 role admin
and I want all the resources with location as US and owner as olaf.
One possible query would be:
select guid from table where attr_subtype = 'location' and attr_value = ‘US'
INTERSECT
select guid from table where attr_subtype = 'owner' and attr_value = ‘himanshu';
There can be any number of attribute name value pairs in the query, so an additional intersection per pair
in the query. I was wondering if we can construct a better query as intersection is expensive.
Assuming you don't have duplicate attributes per GUID you can achieve the desired result without a JOIN:
SELECT "GUID" FROM T
WHERE ( "ATTR_SUBTYPE" = 'location' AND "ATTR_VAL" = 'US' )
OR ( "ATTR_SUBTYPE" = 'owner' AND "ATTR_VAL" = 'himanshu' )
GROUP BY "GUID"
HAVING COUNT(*) = 2 -- <-- keep only GUID have *both* attributes
See http://sqlfiddle.com/#!4/80900/2
Generally, JOIN would be better than INTERSECT here. It gives a chance to get first records prior than several full table scans will finish. But anyway you select a slow data structure so it wouldn't wonderful if it slowdown.
Try something like
select *
from
(select * from table where attr_subtype = 'location' and attr_value = 'US') t1
join
(select * from table where attr_subtype = 'owner' and attr_value = 'himanshu') t2
on (t1.guid = t2.guid)
...
Insert your targets into a temp table then join to it.
select t.guid
from table as t
join temp
on t.attr_subtype = temp.attr_subtype
and t.attr_value = temp.attr_value

How to get all pks after grouping them (finding duplicates)

I have three tables and I am searching for the duplicates in the main table that have the same foreign keys. But I need the primary keys in return of this query:
SELECT ta.fk1, ta.fk2, count(ta.fk2)
FROM ta, tb, tc
WHERE ta.fk2 = tb.pk
AND ta.fk1 = tc.pk
GROUP BY ta.fk1, ta.fk2
HAVING count(ta.fk2) > 1
How can I get the primary keys? Another join or nested query? I tried all I know and found.
Thanks for help.
Something like this maybe?
select distinct ta_pk, tc_pk
from (
select ta.pk as ta_pk,
tc.pk as tc_pk,
count(*) over (partition by ta.fk2) as cnt
from ta
join tb on ta.fk2 = tb.pk
join tc on ta.fk1 = tc.pk
) t
where cnt > 1;