How to access au sub array in bigquery standard SQL? - google-bigquery

in Bigquery standard SQL, I try to select only rows where "tags.value.name" = "start unopen capsule journey" is true
But I dont know how I can access to this stuff.
When I try something like that, it doesn't work :
SELECT my_table.fl_coins_life_time_balance
FROM my_table
WHERE "start unopen capsule journey" IN UNNEST(my_table.tags.value)
This one doesn't work also
SELECT my_table.fl_coins_life_time_balance
FROM my_table
WHERE "start unopen capsule journey" IN UNNEST(my_table.tags)
You can check my Table structure here
I'm sorry for this question who is maybe a noob question, but thx a lot for your help, I'm a little but stuck here ^^

It depends if and where there are arrays inside of your structure. If there are no arrays use this:
With data as (
select struct(struct( "unopen" as name, 8888 as id) as value) tags , 555 fl_coins union all
select struct(struct( "start unopem capsule journey" as name, 8847 as id) as value) tags , 111 fl_coins union all
select struct(struct( "unopen" as name, 8888 as id) as value) tags , 222 fl_coins
)
SELECT
*
FROM
data
where tags.value.name="start unopem capsule journey"
If there is an array use this:
With data as (
select struct([struct( "unopen" as name, 8888 as id)] as value) tags , 555 fl_coins union all
select struct([struct( "start unopem capsule journey" as name, 8847 as id)] as value) tags , 111 fl_coins union all
select struct([struct( "unopen" as name, 8888 as id)] as value) tags , 222 fl_coins
)
SELECT
*,tag_
FROM
data, unnest(data.tags.value) as tag_
where tag_.name="start unopem capsule journey"

Related

stack or union multiple fields in MS Access

Beginner's question here... I have a table of tree measurements being 3 fields: - ID, Diameter_1, Diameter_2
& I wish to get to these 3 fields: - ID, DiameterName, DiameterMeasurement
Input and Desired Output
SELECT DISTINCT ID, Diameter_1
FROM tblDiameters
UNION SELECT DISTINCT ID, Diameter_2
FROM tblDiameters;
Though it results in only 2 fields. How may the field: - DiameterMeasurement be brought in?
Many thanks :-)
You were on the right track to use a union. Here is one viable approach:
SELECT ID, 'Diameter_1' AS DiameterName, Diameter_1 AS DiameterMeasurement
FROM tblDiameters
UNION ALL
SELECT ID, 'Diameter_2', Diameter_2
FROM tblDiameters
ORDER BY ID, DiameterName;

Bigquery: Retrieve information given unique combinations

Currently I have the following R data.table object with product/cities combinations:
product_code place
product1_code city1
product2_code city1
product3_code city1
product4_code city1
product1_code city2
product6_code city2
product9_code city3
What I would like to do is to pass the previous product_code/city combinations to a query string and then pass it to bigrquery. Something like the following:
SELECT *
FROM my.table
WHERE city AND product_code in (list.with.unique.previous.combinations)
However I don't any idea of how I can pass the unique combinations as a list so it only retreives the information for those specific combinations. I know that I can use glue library to pass single elements to the query string something like this:
SELECT *
FROM my.table
WHERE city = {city.selected} AND product_code = {product.code.selected}
but that would only work for 1 combination.
If anyone could give me an idea of how I could pass the entire list of combinations I would appreciate it.
Below example should give you an idea of how it is to be achieved in BigQuery Standard SQL
#standardSQL
WITH combinations AS (
SELECT 'product1_code' product_code, 'city1' place UNION ALL
SELECT 'product2_code', 'city1' UNION ALL
SELECT 'product3_code', 'city1' UNION ALL
SELECT 'product4_code', 'city1' UNION ALL
SELECT 'product1_code', 'city2' UNION ALL
SELECT 'product6_code', 'city2' UNION ALL
SELECT 'product9_code', 'city3'
)
SELECT *
FROM `project.dataset.table` t
WHERE (city, product_code) IN (
SELECT AS STRUCT place, product_code
FROM combinations
)
As you can see you need to combine city and product_code into STRUCT - (city, product_code) and look for it in list of combinations presented also as a struct via SELECT AS STRUCT place, product_code FROM combinations

SQL unique combinations

I have a table with three columns with an ID, a therapeutic class, and then a generic name. A therapeutic class can be mapped to multiple generic names.
ID therapeutic_class generic_name
1 YG4 insulin
1 CJ6 maleate
1 MG9 glargine
2 C4C diaoxy
2 KR3 supplies
3 YG4 insuilin
3 CJ6 maleate
3 MG9 glargine
I need to first look at the individual combinations of therapeutic class and generic name and then want to count how many patients have the same combination. I want my output to have three columns: one being the combo of generic names, the combo of therapeutic classes and the count of the number of patients with the combination like this:
Count Combination_generic combination_therapeutic
2 insulin, maleate, glargine YG4, CJ6, MG9
1 supplies, diaoxy C4C, KR3
One way to match patients by the sets of pairs (therapeutic_class, generic_name) is to create the comma-separated strings in your desired output, and to group by them and count. To do this right, you need a way to identify the pairs. See my Comment under the original question and my Comments to Gordon's Answer to understand some of the issues.
I do this identification in some preliminary work in the solution below. As I mentioned in my Comment, it would be better if the pairs and unique ID's existed already in your data model; I create them on the fly.
Important note: This assumes the comma-separated lists don't become too long. If you exceed 4000 characters (or approx. 32000 characters in Oracle 12, with certain options turned on), you CAN aggregate the strings into CLOBs, but you CAN'T GROUP BY CLOBs (in general, not just in this case), so this approach will fail. A more robust approach is to match the sets of pairs, not some aggregation of them. The solution is more complicated, I will not cover it unless it is needed in your problem.
with
-- Begin simulated data (not part of the solution)
test_data ( id, therapeutic_class, generic_name ) as (
select 1, 'GY6', 'insulin' from dual union all
select 1, 'MH4', 'maleate' from dual union all
select 1, 'KJ*', 'glargine' from dual union all
select 2, 'GY6', 'supplies' from dual union all
select 2, 'C4C', 'diaoxy' from dual union all
select 3, 'GY6', 'insulin' from dual union all
select 3, 'MH4', 'maleate' from dual union all
select 3, 'KJ*', 'glargine' from dual
),
-- End of simulated data (for testing purposes only).
-- SQL query solution continues BELOW THIS LINE
valid_pairs ( pair_id, therapeutic_class, generic_name ) as (
select rownum, therapeutic_class, generic_name
from (
select distinct therapeutic_class, generic_name
from test_data
)
),
first_agg ( id, tc_list, gn_list ) as (
select t.id,
listagg(p.therapeutic_class, ',') within group (order by p.pair_id),
listagg(p.generic_name , ',') within group (order by p.pair_id)
from test_data t join valid_pairs p
on t.therapeutic_class = p.therapeutic_class
and t.generic_name = p.generic_name
group by t.id
)
select count(*) as cnt, tc_list, gn_list
from first_agg
group by tc_list, gn_list
;
Output:
CNT TC_LIST GN_LIST
--- ------------------ ------------------------------
1 GY6,C4C supplies,diaoxy
2 GY6,KJ*,MH4 insulin,glargine,maleate
You are looking for listagg() and then another aggregation. I think:
select therapeutics, generics, count(*)
from (select id, listagg(therapeutic_class, ', ') within group (order by therapeutic_class) as therapeutics,
listagg(generic_name, ', ') within group (order by generic_name) as generics
from t
group by id
) t
group by therapeutics, generics;

Get Identity after selecting from distinct result

i have 2 tables ( Model_Table , Items_Table)
Model_Tabl ( ID, ModelName, ModelQuantity)
Items_Tabl ( I_Code, IName, ID)
after inserting new row into (Model_Table) - Triggers insert multi row into (Items_Table) Depend on ModelQuantity from (Model_Table)
, and until now its work fine
I Created "select distinct ModelName , Sum(ModelQuantity) group by ModelName"
and i got result fine
My question is :
When i select model name from (DISTINCT) query i want to know which (ID) I selected from (Model_Table)
Model_ID (TO) Model_Name = 1 (TO) Many
ty
just do:
select ID, ModelName , Sum(ModelQuantity) group by ID, ModelName
as long as ID and ModelName are 1-to-1, you're good.
(Btw, your "distinct" here is superfluous - Select distinct a,b,c from tbl is simply shorthand for Select a,b,c from tbl group by a,b,c)
You have an identity column in the model_table, but you don't appear to be using it in the query where you check the ModelQuantity field. Don't you want to do something like this?
select ModelQuantity
from Model_table
where id = ##identity
?
First of all, you don't need the DISTINCT there, so you can get rid of it. And then, you can try this:
SELECT ID, ModelName, SUM(ModelQuantity) Quantity
FROM Model_Tabl
GROUP BY ID, ModelName
Ok, as I explained on my comment, if you have multiple IDs with the same name, you need to choose one, either the max or the min ID (it still doesn't make sense that you are going to end up just choosing one ID when you actually need to identify that ID), but well, here it is:
SELECT MIN(ID) ID, ModelName, SUM(ModelQuantity) Quantity
FROM Model_Tabl
GROUP BY ModelName

Selecting distinct values for multiple columns

I have a table where many pieces of data match to one in another column, similar to a tree, and then data at the 'leaf' about each specific leaf
eg
Food Group Name Caloric Value
Vegetables Broccoli 100
Vegetables Carrots 80
Fruits Apples 120
Fruits Bananas 120
Fruits Oranges 90
I would like to design a query that will return only the distinct values of each column, and then nulls to cover the overflow
eg
Food group Name Caloric Value
Vegetables Broccoli 100
Fruit Carrots 80
Apples 120
Bananas 90
Oranges
I'm not sure if this is possible, right now I've been trying to do it with cases, however I was hoping there would be a simpler way
Seems like you are simply trying to have all the distinct values at hand. Why? For displaying purposes? It's the application's job, not the server's. You could simply have three queries like this:
SELECT DISTINCT [Food Group] FROM atable;
SELECT DISTINCT Name FROM atable;
SELECT DISTINCT [Caloric Value] FROM atable;
and display their results accordingly.
But if you insist on having them all in one table, you might try this:
WITH atable ([Food Group], Name, [Caloric Value]) AS (
SELECT 'Vegetables', 'Broccoli', 100 UNION ALL
SELECT 'Vegetables', 'Carrots', 80 UNION ALL
SELECT 'Fruits', 'Apples', 120 UNION ALL
SELECT 'Fruits', 'Bananas', 120 UNION ALL
SELECT 'Fruits', 'Oranges', 90
),
atable_numbered AS (
SELECT
[Food Group], Name, [Caloric Value],
fg_rank = DENSE_RANK() OVER (ORDER BY [Food Group]),
n_rank = DENSE_RANK() OVER (ORDER BY Name),
cv_rank = DENSE_RANK() OVER (ORDER BY [Caloric Value])
FROM atable
)
SELECT
fg.[Food Group],
n.Name,
cv.[Caloric Value]
FROM (
SELECT fg_rank FROM atable_numbered UNION
SELECT n_rank FROM atable_numbered UNION
SELECT cv_rank FROM atable_numbered
) r (rank)
LEFT JOIN (
SELECT DISTINCT [Food Group], fg_rank
FROM atable_numbered) fg ON r.rank = fg.fg_rank
LEFT JOIN (
SELECT DISTINCT Name, n_rank
FROM atable_numbered) n ON r.rank = n.n_rank
LEFT JOIN (
SELECT DISTINCT [Caloric Value], cv_rank
FROM atable_numbered) cv ON r.rank = cv.cv_rank
ORDER BY r.rank
I guess what I would want to know is why you need this in one result set? What does the code look like that would consume this result? The attributes on each row have nothing to do with each other. If you want to, say, build the contents of a set of drop-down boxes, you're better off doing these one at a time. In your requested result set, you'd need to iterate through the dataset three times to do anything useful, and you would need to either check for NULL each time or needlessly iterate all the way to the end of the dataset.
If this is in a stored procedure, couldn't you run three separate SELECT DISTINCT and return the values as three results. Then you can consume them one at a time, which is what you would be doing anyway I would guess.
If there REALLY IS a connection between the values, you could add each of the results to an array or list, then access all three lists in parallel using the index.
Something like this maybe?
select *
from (
select case
when row_number() over (partition by fruit_group) = 1 then fruit_group
else null
end as fruit_group,
case
when row_number() over (partition by name) = 1 then name
else null
end as name,
case
when row_number() over (partition by caloric) = 1 then caloric
else null
end as caloric
from your_table
) t
where fruit_group is not null
or name is not null
or caloric is not null
But I fail to see any sense in this