I have data in a BigQuery table where every row is an item in an ecommerce order, for example here are rows showing the purchase of three items across two orders:
Order number
Product
Quantity
001
ABC
1
001
DEF
2
002
GHI
1
I need to create a JSON list for every order in the below format, which using the example data above would look like this for order 001:
[ {product_id: "ABC", quantity:1},{product_id: "DEF", quantity:2} ]
How can I achieve this format in BigQuery SQL?
Consider below
SELECT order_number,
TO_JSON_STRING(ARRAY_AGG(STRUCT(product as product_id, quantity))) json_value
FROM orders
GROUP BY order_number
if applied to sample data in your question - output is
As #aleix-cc pointed out, this can be easily done with the TO_JSON function which is currently in preview:
WITH orders as (
SELECT "001" as order_number, "ABC" as product, 1 as quantity UNION ALL
SELECT "001", "DEF", 2 UNION ALL
SELECT "002", "GHI", 1
)
SELECT
order_number,
TO_JSON(ARRAY_AGG(STRUCT(product, quantity))) json_value
FROM orders
GROUP BY order_number
Edit: Since this is a function in preview, you should go with Mikhail's answer and use TO_JSON_STRING.
Related
I'm trying to create a VIEW of a JSON object, with a varying number of key/value pairs, in PostgreSQL v14.x, from the results of a SELECT statement.
Using json_agg is returning an array of objects - a key of each rating possibility as they occur, and a value which is the count of all the ratings selected from a table of reviews. Instead of an array, I need an object that has multiple key/value pairs, where the value corresponds to the aggregated count() of the ratings column(s), grouped by product_id. Trying to reuse json_build_object isn't working as expected.
Using:
CREATE VIEW reviews.meta AS
SELECT product_id, json_agg(json_build_object(reviews.list.rating, reviews.list.rating))
FROM reviews.list
GROUP BY reviews.list.product_id
ORDER BY product_id;
returns:
product_id | reviews_count
---------------------------
1 | [{"5" : 5}, {"4" : 4}]
2 | [{"4" : 4}, {"4" : 4}, {"3" : 3}, {"5" : 5}, {"2" : 2}]
But I'm looking for:
product_id | reviews_count
---------------------------
1 | {"5" : 1, "4" : 1}
2 | {"4" : 2, "3" : 1, "5" : 1, "2" : 1}
A dynamically created object:
in rows by product_id
where the values are quantities of Integer ratings (1-5) as they appear in the reviews.list table
in an object rather than an array of objects
I am new to SQL / PL/pgSQL language.
You need two levels of aggregation, one to get the counts, and one to package the counts up. It is easy to do that by nesting one query inside the FROM of another:
CREATE or replace VIEW meta AS
SELECT product_id, jsonb_object_agg(rating, count)
FROM (select product_id, rating, count(*) from list group by product_id, rating) foo
GROUP BY product_id
ORDER BY product_id;
Is there a function in SQL for Bigquery where I can merge a repeating value?
This is the data
Date
Product
total_session_by_day
July 1
Product A
200
July 1
Product B
200
July 2
Product A
500
July 2
Product B
500
And this is the desired output in Bigquery.
Excel Output
The idea is when I select "July 1 and 2" and "Product A and/or B" on datastudio, the value of total_session_by_day is 700.
Hope someone could help. Thank you.
Replace SourceTable with your table's id:
SELECT
total_session_by_day,
ARRAY_AGG(
STRUCT(
`Date`,
Product
) AS r
)
FROM SourceTable
GROUP BY total_session_by_day
The output will look like this:
I hope my title is ok as I really don’t know how to call it.
Anyway, I have a table with the following :
ID - Num (Primary Key)
Category - VarChar
Name - VarChar
DateForName - Date
Data looks like that :
1 100 111 31/12/2017
2 101 210 30/12/2017
3 100 112 29/12/2017
4 101 203 27/12/2017
5 100 117 20/12/2017
6 103 425 08/12/2017
To generate this table, I just sorted by date DESC.
Is there a way to add a new column with the order per Category like :
1 100|1
2 101|1
3 100|2
4 101|2
5 100|3
6 103|1
Max
You want analytical function row_number():
select t.*
from (select *, row_number() over (partition by Category order by date desc) Seq
from table
) t
order by id;
Yes, SQL has a couple options for you to add a column that is populated with a ranking of the rows based on the category and id columns.
If you just want to add a column to the select statement, I recommend using the RANK() function.
See more details here:
https://learn.microsoft.com/en-us/sql/t-sql/functions/rank-transact-sql?view=sql-server-2017
For your current table, try the following select statement:
SELECT
[ID],
[Category],
[Name],
[DateForName],
RANK() OVER (PARTITION BY [Category] ORDER BY [DateForName] DESC) AS [CategoryOrder]
FROM [TableName]
Alternatively, if you want to add a permanent column (aka a field) to the existing table, I recommend treating this as a calculated column. See more information here:
https://learn.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-2017
Because the new column would be completely based on two pre-existing columns and only those two columns. SQL can do a great job maintaining this for you.
Hope this helps!
I have data from 1 table with single row data
link : https://www.dropbox.com/s/86j2o9jo9v8vqip/stack1.PNG?dl=0
Function dateMarine NumberMarine dateBOC NumberBOC Status
------------------------------------------------------------------------------
Shipping 2000/01/01 10 2007/01/01 11 Paid
And I want to create multiple row from single row data 1 shipmentNumber , like this
Function No.Doc date status
--------------------------------------
Shipping 10 2000/01/01 Paid
Shipping 11 2007/01/01 Paid
How to create query for this case, I have some reference like this:
SELECT [Date]
, API
, LEFT(col,CHARINDEX('_',col)-1)'Latency'
, RIGHT(col,CHARINDEX('_',REVERSE(col))-1)'Aggregation'
, Value
FROM
(
SELECT [Date],API,col,value
FROM Table1
CROSS APPLY
(
VALUES ('Latency1_Avg', [Latency1_Avg]),('Latency1_Min', [Latency1_Min]),('Latency1_Max', [Latency1_Max]),('Latency2_Avg', [Latency2_Avg]),('Latency2_Min', [Latency2_Min]),('Latency2_Max', [Latency2_Max])
) C (COL, VALUE)
) SRC
But i think my case is different
sorry i use the link to show picture of my case, because i cant import pic in my stackoverflow account
Thankyou for youre helping me
I'm wondering if there is a way to modify the results of one of my queries. Right now, I have a query in which the output shows the number of items in certain type of category by date, by using the Group By feature. So just as an example, if I enter 9/15/13 as the date the output would be as follows:
Apples 1
Bannas 5
Pears 16
Is there a way for it to just show Apples and total all other items into one category so it would output:
Apples 1
All Others 21
Thanks in advance for all of your help!
A bit difficult without table names or column names, but something along the lines of this (you'll have to enter it in SQL view)
Select
IIf([Product] = 'Apples', 'Apples', 'All Others'),
Count(*)
From
[Inventory]
Where
[InventoryDate] = [Enter Date]
Group By
IIf([Product] = 'Apples', 'Apples', 'All Others')
You need to replace Inventory with your table name, and Product with the column that contains the category and InventoryDate with the column that has the date. Count(*) might be sum([Quantity]), it depends on your structure.