Big Query - ANY_VALUE returning Null - google-bigquery

I am trying to use "any_value" function in BQ but it keeps me returning NULL.
Below is the case example of my problem.
Important to note that it is working fot tid field but not for seller (the one I really need)
I have no idea why it is happening.
select
*
, any_value(seller) over (partition by gid) as other_seller
, any_value(tid) over (partition by gid) as other_tid
FROM `my_Table`

I have no idea why it is happening.
ANY_VALUE behaves as if RESPECT NULLS is specified; rows for which expression is NULL are considered and may be selected.
Consider below option then
select
*
, max(seller) over (partition by gid) as other_seller
, max(tid) over (partition by gid) as other_tid
FROM `my_Table`
In case if you want to randomize output - try below
select
*
, first_value(seller) over (partition by gid order by if(seller is null, 1, rand())) as other_seller
, first_value(tid) over (partition by gid order by if(tid is null, 1, rand())) as other_tid
FROM `my_Table`

Related

SQL Server : return all rows in set if one row has value equal to target value

I'm currently working on a SQL query that searches an "archive" database and returns a row for each change that occurred on an order from the beginning of time to today.
What I would like to do with this query is only return the orders that are currently or have been associated with a specific order handler. The best way for me to explain it is that every order is currently grouped in a "set" with a row number for each change, but if one of the rows ever holds the value I'm looking for either "handler" columns, I want it to return all the rows, not just the one with that target value.
Here is what I have so far.
SELECT
ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY EventDateTime) AS RowNumber,
ace.[OrderId],
ace.[OrderHandler],
ace.[EventDateTime],
ace.[OrderStatus],
LAG(ace.[OrderHandler], 1) OVER (PARTITION BY [OrderId] ORDER BY ace.[EventDateTime]) AS PreviousOrderHandler,
LAG(ace.[EventDateTime], 1) OVER (PARTITION BY [OrderId] ORDER BY ace.[EventDateTime]) AS PreviousEventDateTime,
LAG(ace.[OrderStatus], 1) OVER (PARTITION BY [OrderId] ORDER BY ace.[EventDateTime]) AS PreviousOrderStatus
FROM
Archive AS ace
Here is the sample data I receive when running the above query:
So instead of just returning row number 9 where the OrderHandler = POOL, I want to query if the OrderId has an OrderHandler of POOL at ANY TIME in history, return all the rows.
I figured I could potentially use a WHERE EXISTS but I'm not sure how I could return the whole set of results instead of just the results that match.
Any help is extremely appreciated!
You can use exists like this:
select a.*
from ace a
where exists (select 1
from ace a2
where a2.orderid = a.orderid and
a2.orderhandler = #orderhandler
);
Script for solution:
SELECT ROW_NUMBER() OVER (PARTITION BY ace.OrderId ORDER BY ace.EventDateTime) AS RowNumber
,ace.[OrderId]
,ace.[OrderHandler]
,ace.[EventDateTime]
,ace.[OrderStatus]
,LAG(ace.[OrderHandler], 1) OVER ( PARTITION BY ace.[OrderId] ORDER BY ace.[EventDateTime] ) as PreviousOrderHandler
,LAG(ace.[EventDateTime], 1) OVER ( PARTITION BY ace.[OrderId] ORDER BY ace.[EventDateTime] ) as PreviousEventDateTime
,LAG(ace.[OrderId], 1) OVER (PARTITION BY ace.[OrderId] ORDER BY ace.[OrderId] ) as PreviousOrderId
,LAG(ace.[OrderStatus], 1) OVER ( PARTITION BY ace.[OrderId] ORDER BY ace.[EventDateTime] ) as PreviousOrderStatus
FROM Archive as ace
WHERE EXISTS
(SELECT * FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY EventDateTime) AS RowNumber
,ace.[OrderId]
,ace.[OrderHandler]
,ace.[EventDateTime]
,ace.[OrderStatus]
FROM Archive as ace
GROUP BY ace.[OrderId]
,ace.[OrderHandler]
,ace.[EventDateTime]
,ace.[OrderStatus]
HAVING ace.OrderHandler LIKE '%POOL%'
)x
WHERE ace.OrderId = x.OrderId)

How do I get just one column with this code?

I have a table which name is product barcode and i want to return one column by using executescalar .I dont want to return datatable.Nevertheless my query returs rows .I just need barcode. Please help !!
I can figure out the problem by using recursive select loop but ı want to solve this problem by using partition by .
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc )
from PRODUCT_BARCODE
where PRODUCT_NO='111333666';
I expect output like this:
25000111133335555
it will return barcode like this. Query execution
If you only want the barcode from the row with the highest product_barcode_type_code for the specified product then you can do it without a subquery or explicit ranking function using last:
select max(barcode) keep (dense_rank last order by product_barcode_type_code) as barcode
from product_barcode
where product_no = 111333666;
You can include a partition by clause but there's no point as you're filtering on a single product_no anyway.
Very quick demo:
-- CTE for sample data
with product_barcode (product_no, product_barcode_type_code, barcode) as (
select 111333666, 1, 1234 from dual
union all select 111333666, 2, 2345 from dual
union all select 111333666, 3, 25000111133335555 from dual
)
select max(barcode) keep (dense_rank last order by product_barcode_type_code) as barcode
from product_barcode
where product_no = 111333666;
BARCODE
-----------------
25000111133335555
(I've assumed your product_no, at least, is a number type rather than a string, and thus omitted the single quotes you had around the literal value you're searching for; but if it is actually a string then include those of course..)
Select BARCODE + PRODUCT_BARCODE_TYPE_CODE + partBarCode
FROM
(
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by
PRODUCT_BARCODE_TYPE_CODE desc ) as partBarCode
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
) as res
This assumes that all fields are of the same type Nvarchar() else they will be summarized as per integer.
Select to_char (BARCODE ) || to_char( PRODUCT_BARCODE_TYPE_CODE) from (
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc ) rn
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
)
Where rn = 1;
You can try below -
select concat(BARCODE,PRODUCT_BARCODE_TYPE_CODE) as barcode from
(
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc ) as rn
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
)A where rn=1

Finding row with max values in two groups

I use SQL Server 2012,
I have a following table:
id, name, surname, timestamp, type
type has two possible values: 1 and 2.
Now, I would like to find two rows - for each group (1 and 2) row with maximal value in particular type.
The problem is that I would like to find both name and surname.
I can do it with SELECT TOP 1 - WHERE ORDER BY - UNION approach, but I would like to find antother, better idea.
Can you help me ?
This sounds like you want the most recent for each row, for each type. If that's the case, here is a way with row_number()
with cte as(
select
id
,name
,surname
,timestamp
,type
RN = row_number() over (partition by id,type order by timestamp desc))
select *
from cte
where RN = 1

SQL Identify Cloud ID's

I am analyzing a data set. Table has 3 columns:
-CLOUD_ID (ID Field) example: 121312
-CURRENT_Action (Textfield) example: Started
-MIN_STARTDATE (Date) example: 2016-04-20 17:03:58.633
I need to identify the Cloud_ID's which don't have the Current_Action "Deleted" as the minimum MIN_Startdate.
You can use window functions:
select distinct cloud_id
from (select t.*,
min(min_startdate) over (partition by cloud_id) as min_min_startdate
from t
) t
where min_startdate = min_min_startdate and
Current_Action <> 'Deleted';
Note: This assumes that Current_Action is not NULL, but that could easily be included in the logic.
A sligtly different approach, pls compare the perf:
with x as (select *, row_number() over(partition by cloud_id order by min_startdate) rn from #t)
select cloud_id from x where rn = 1 and current_action <> 'deleted'

SQL server - SELECT a columns entry on a CASE WHEN query

I'd like to find out the first provider (PROVIDER_ID) to the client (CLIENT_ID) in a database table of bookings (BOOKING_ID)
I currently SELECT the CLIENT_ID first, then calculate various other things.
I group by (CLIENT_ID) and the count is correct.
What I'm looking for is
SELECT case when(min(BOOKING_ID)) then PROVIDER_ID else null end)
But I am unable to perform sub queries within the SELECT/CASE WHEN
I hope this makes sense and the question is clear.
Ideally I would like a solution that is within a single SELECT
Assuming you want to get the PROVIDER_ID for the MIN(BOOKING_ID) grouping by CLIENT_ID the following should work:
SELECT
Client_ID,
Booking_ID,
Provider_ID
FROM (
SELECT
Client_ID,
Provider_ID,
Booking_ID,
ROW_NUMBER() OVER (PARTITION BY Client_ID ORDER BY Booking_ID) as RowNumber
FROM
Bookings
) OrderedTable
WHERE
OrderedTable.RowNumber = 1
How does it work? ROW_NUMBER OVER (ORDER BY field) gives you the row number if the result set was ordered by a particular field. The PARTITION BY field allows you to partition the table by a particular key (in this case Client_ID) that will reset the ROW_NUMBER for each Client_ID (so if RowNumber = 1, it's the first entry for that particular client)
More details here: http://msdn.microsoft.com/en-us/library/ms186734.aspx
Using WITH syntax:
WITH OrderedTable AS
(
SELECT
Client_ID,
Provider_ID,
Booking_ID,
ROW_NUMBER() OVER (PARTITION BY Client_ID ORDER BY Booking_ID) as RowNumber
FROM
Bookings
)
SELECT
Client_ID,
Provider_ID,
Booking_ID
FROM
OrderedTable
WHERE
RowNumber = 1