How to create list from long data in bigquery? - google-bigquery

Hi I have a table like so
orderId
productId
1
23
1
24
1
27
2
25
2
26
3
27
and want to transform it into
orderId
productIds
1
23,24,27
2
25,26
3
27
How do I achieve this?

Use STRING_AGG:
SELECT orderId, STRING_AGG(productId ORDER BY productId) AS productIds
FROM yourTable
ORDER BY orderId;

Related

Select TOP 2 maximum values in SQL

I neet to select TOP 2 products with Max Price.
ProductID ProductName SupplierID CategoryID Unit Price
1 Chais 1 1 10 bags 18
2 Chang 1 1 24 bottles 19
3 Aniseed Syrup 1 2 12 bottles 10
I have used:
Select TOP 2 *
from Products
where Price = (Select Max(Price) from Products);
But the result is just 1 row.
This will give you the top 2 max prices but if the same price is in there twice you would get the same value twice, but from your code above that is what it would do so assuming that is what you are looking for.
Select TOP 2 * from Products order by Price DESC
You need order by clause :
select top (2) *
from Products p
order by price desc;

How to get 2 most recent values in postgreSQL in one row?

I have this table of items in order:
orderitemid orderid itemid quantity price createdate
1 1 12 5 15.5 2016-12-04 11:35:02.06629
2 1 17 5 13.2 2016-12-04 11:32:02.06629
3 2 12 2 12.5 2016-12-05 11:35:02.06629
4 2 17 1 12.6 2016-12-05 11:35:02.06629
5 2 18 15 14.5 2016-12-04 11:35:02.06629
6 3 12 45 3 2015-12-04 11:35:02.06629
I have a query which gives the most recent order of each item so:
select distinct on (itemid) *
from orderitems
order by itemid,createdate
this gives:
orderitemid orderid itemid quantity price createdate
3 2 12 2 12.5 2016-12-05 11:35:02.06629
4 2 17 1 12.6 2016-12-05 11:35:02.06629
5 1 18 15 14.5 2016-12-04 11:35:02.06629
Now what I want is to get in the same row per item information about the previous order of the item. Basically to compare the most recent order of item with the 2nd most recent order of item
This is what I want:
orderitemid itemid quantity price 2ndquantity 2ndprice 2ndorderitemid
3 12 2 12.5 5 15.5 1
4 17 1 12.6 1 13.2 2
5 18 15 14.5
How can I modify my query to do that?
with ranked as (
select orderitemid, orderid, itemid, quantity, price, createdate,
row_number() over (partition by itemid order by createdate desc) as rn
from orderitems
)
select r1.*, r2.quantity as "2ndquantity", r2.price as "2ndprice",
r2.orderitemid as "2ndorderitemid"
from ranked r1
left join ranked r2 on r1.itemid = r2.itemid and r2.rn = 2
where r1.rn = 1;
The CTE calculates the 1st and 2nd items and the final select then brings them together with a join. Note that you need a left join as there might not be a 2nd row and in that case that item would not show up at all.
Online example: http://rextester.com/SDBZ21144
Hmmm you want to compare all orderitem rows against the next most recent price?
WITH comparison_rank AS (
SELECT orderitemid, itemid, price, quantity
rank() over (partition by itemid order by createddate)
FROM orderitems
)
SELECT o.orderitemid, o.itemid, o.price, o.quantity, o.price, o.createddate,
p.price as prevprice, p.quantity as prevqty
FROM orderitems o JOIN comparison_rank c ON o.orderitemid = c.orderitemid
LEFT JOIN comparison_rank p ON c.rank = p.rank + 1 AND c.itemid = p.itemid;
This will not perform so well over a large data set however. To improve performance I think you need to improve your data model to improve performance.

complex paratition sum in postgresql

I have tables as follow:
A deliveries
delveryid clientid deliverydate
1 10 2015-01-01
2 10 2015-02-02
3 11 2015-04-08
B items in deliveris
itemid deliveryid qty status
70 1 5 1
70 1 8 2
70 2 10 1
72 1 12 1
70 3 100 1
I need to add a column to my query that gives me the qty of each part in other deliveris of the same client.
meaning that for given data of client 10 and delivery id 1 I need to show:
itemid qty status qtyOther
70 5 1 10 //itemid 70 exists in delivery 2
70 8 2 10 //itemid 70 exists in delivery 2
72 12 1 0 //itemid 72 doesn't exists in other delivery of client 11
Since I need to add qtyOther to my existing qry i'm trying to avoid using Group By as it's a huge query and if I use SUM in select I will have to group by all items in select.
This is what I have so far:
Select ....., coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) ,0) AS qtyOther
FROM B b
LEFT JOIN A a USING
LEFT JOIN (other tables)
WHERE clientid=10 ....
This query gives me the total sum of qty per itemid for specific clientid, regardless of which delivery it is. How do I change it so it will consider the delivryid? I need something like:
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) FROM B where deliveryid<>b.deliveryid ,0) AS qtyOther
Any suggestions how to do that?
Note: I can NOT change the condition in WHERE.
I think you just want to subtract out the total for the current delivery:
Select .....,
(coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid), 0) -
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid, a.deliveryid), 0)
) as qtyOther

Need a query to find count of a column record?

I have a table like this,
ProductId CategoryID bIsPrimary
1 5 1
1 6 0
1 7 0
2 18 1
2 19 1
I need a output like this,
ProductID PrimaryCategoryCount
1 1
2 2
Basically i need to find the the number of primary categories for each product.
SELECT ProductId, COUNT(*)
FROM SomeTable
WHERE bIsPrimary <> 0
GROUP BY ProductId
SELECT
ProductId
,sum(case when bIsPrimary = 1 then 1 else 0 end) as PrimaryCategoryCount
from
Table
group by
ProductId
or
SELECT
ProductId
,count(CategoryId)
from
Table
where bIsPrimiary = 1
group by ProductId
Both will provide you the same result. Pick up one which suits you more or is faster.
SELECT ProductId, COUNT(bIsPrimary)
FROM yourTable
GROUP BY ProductId
This is how I'd do it. WHERE clause isn't necessary here if I'm not mistaken.

Get 1 row from multiple columns

I have 2 tables
table#1: Order
orderid unitid active
1 aa 1
2 bb 0
3 cc 1
4 dd 1
table#2:Details
orderid month
1 6
1 7
1 12
2 1
2 6
3 1
3 2
3 3
3 4
3 6
Output desired:
orderid unitid jan feb mar apr may jun ......... dec
1 aa yes yes
3 cc yes yes yes yes
For all orders where ACTIVE is 1 and all unitids.
I tried using case statement, i get multiple rows for a single orderid, which is not how i want.
I see a lot of examples for pivot with one table, how to do this using 2 tables? I am using SQL Server 2012.
Maybe a Select within a SELECT as argument
Something like this;
Select orderid, unitid, (SELECT month
From Table2
WHERE ...)
From table1
Where ...
I am referencing with this answer this Issue:
A select query selecting a select statement