Mark values with diffreent tag in sql - sql

I have one endpoint that is 7. I would like to few numbers 40,35,30,26,22,18,12 mark as completed.(This is an example. The value may be different) and few numbers 13,17,21,27,32,38,43 mark as pending. (This is an example. The value may be different) Can we achieve by SQL statement? for number details, please find the image.

If your DBMS supports Windowed Aggregates:
with cte as
( select ID, point,
-- find all rows after the latest 7 row
sum(case when point = 7 then 1 end)
over (order by ID DESC) as cumsum
from tab
)
select ID, point,
case when point = 7 then 'endpoint'
when cumsum is null then 'pending' -- no 7 after those IDs
else 'completed'
end
from cte

If you want everything before the first "7" as "completed" and the rest as "pending", then you can use window functions and cumulative logic. One method is:
select t.*,
(case when point = 7 then null
when id < min(case when point = 7 then id end) over ()
then 'complete'
else 'pending'
end) as mark
from t ;

Related

Is there a way to collect the data and inspect in one pass using groupby function

Sample Data of table_1
Have this Query that returns
select
customer,
SUM(CASE WHEN activity IN ( 'a','b')
THEN 1
ELSE 0 END) AS num_activity_a_or_b
from table_1
group by customer
Results:
Want to extend this to return one more column if for a given code say X1 if the Activity is "a" and "c" then return num_of_a_and_c_activity.
A bit stuck how to collect and inpect the code and activities in one pass.
can we combine windowing function to achieve this.
Please advise and help
UPDATE:
based on the updated results, maybe the below query is what you need
So what i assume is that you need both a and c as well x1 .
So I count distinct activities which are a and c and then do integer division by 2. if only a is present then count distinct =1 but 1/2 =0 in integer division.
It is only 1 when both a and c are present.
select
customer,
SUM(CASE WHEN activity IN ( 'a','b')
THEN 1
ELSE 0
END) AS num_activity_a_or_b,
COUNT(DISTINCT CASE WHEN code IN ('x1') AND activity IN ( 'a','c')
THEN activity
ELSE NULL
END)/2 AS num_activity_a_and_c
from table_1
group by customer
Maybe your query can be
select
customer,
SUM(CASE WHEN activity IN ( 'a','b')
THEN 1
ELSE 0
END) AS num_activity_a_or_b,
SUM(CASE WHEN code IN ('x1') AND activity IN ( 'a','c')
THEN 1
ELSE 0
END) AS num_activity_a_or_c
from table_1
group by customer

Creating flag column

I would like to ask you for your help. I want to create a flag column, that will mark specific contract numbers whith 1, where the "CLOSED" column is empty in some rows.
I tried
case when CLOSED is null then 1 else 0 end as flag
group by CONTRACT_NUMBER
but it's not working. Thank you for your responses
example picture
I think you need analytic max() here:
demo
select t.*,
max(case when closed is null
then 1
else 0
end) over (partition by contract_number) as flag
from t

reward points and allocate those points in the original table's field

I have a table here :
I want to reward a gold and a silver(i.e a value of 1 wherever applicable,else 0 )to top 2 persons by looking at pointsRewarded field.
I already have the first table created .I have modified it with the extra fields that I want i.e rank,gold,silver fields.It has null values now.
i want the output to be something like this:
I have tried some query :
update dbo.original
set rnk = dense_rank() over (partition by WeekNumber order by pointsrewarded desc)
set gold =
case when rnk = '1' then 1 else 0 end
set silver =
case when rnk = '2' then 1 else 0 end
I already have modified the table design by adding the rnk,gold and silver fields.I want the values generated by the query to go and sit in those fields.
Please help me with the query or give me some suggestions on how to proceed.Please.
Thanks a lot.
This seems like a follow-up to your earlier question.
In SQL Server you can use an updatable CTE:
with toupdate as (
select o.*,
dense_rank() over (partition by WeekNumber order by pointsrewarded desc) as new_rnk
from dbo.original
)
update toupdate
set rnk = new_rank,
gold = (case when rnk = 1 then 1 else 0 end),
silver = (case when rnk = 2 then 1 else 0 end);
Note: Only use single quotes for string and date constants. Do not use single quotes for numeric constants.

Constructing A Query In BigQuery With CASE Statements

So I'm trying to construct a query in BigQuery that I'm struggling with for a final part.
As of now I have:
SELECT
UNIQUE(Name) as SubscriptionName,
ID,
Interval,
COUNT(mantaSubscriptionIdmetadata) AS SubsPurchased,
SUM(RevenueGenerated) as RevenueGenerated
FROM (
SELECT
mantaSubscriptionIdmetadata,
planIdmetadata,
INTEGER(Amount) as RevenueGenerated
FROM
[sample_internal_data.charge0209]
WHERE
revenueSourcemetadata = 'new'
AND
Status = 'Paid'
GROUP BY
mantaSubscriptionIdmetadata,
planIdmetadata,
RevenueGenerated
)a
JOIN (
SELECT
id,
Name,
Interval
FROM
[sample_internal_data.subplans]
WHERE
id in ('150017','150030','150033','150019')
GROUP BY
id,
Name,
Interval )b
ON
a.planIdmetadata = b.id
GROUP BY
ID,
Interval,
Name
ORDER BY
Interval ASC
The resulting query looks like this
Which is exactly what I'm looking for up to that point.
Now what I'm stuck on this. There is another column I need to add called SalesRepName. The resulting field will either be null or not null. If its null it means it was sold online. If its not null, it means it was sold via telephone. What I want to do is create two additional columns where it says how many were sold via telesales and via online. The sum total of the two columns will always equal the SubsPurchased total.
Can anyone help?
You can include case statements within aggregate functions. Here you could choose sum(case when SalesRepName is null then 1 else 0 end) as online and sum(case when SalesRepName is not null then 1 else 0 end) as telesales.
count(case when SalesRepName is null then 1 end) as online would give the same result. Using sum in these situations is simply my personal preference.
Note that omitting the else clause is equivalent to setting else null, and null isn't counted by count. This can be very useful in combination with exact_count_distinct, which has no equivalent in terms of sum.
Try below:
it assumes your SalesRepName field is in [sample_internal_data.charge0209] table
and then it uses "tiny version" of SUM(CASE ... WHEN ...) which works when you need 0 or 1 as a result to be SUM'ed
SUM(SalesRepName IS NULL) AS onlinesales,
SUM(NOT SalesRepName IS NULL) AS telsales
SELECT
UNIQUE(Name) AS SubscriptionName,
ID,
Interval,
COUNT(mantaSubscriptionIdmetadata) AS SubsPurchased,
SUM(RevenueGenerated) AS RevenueGenerated,
SUM(SalesRepName IS NULL) AS onlinesales,
SUM(NOT SalesRepName IS NULL) AS telesales
FROM (
SELECT SalesRepName, mantaSubscriptionIdmetadata, planIdmetadata, INTEGER(Amount) AS RevenueGenerated
FROM [sample_internal_data.charge0209]
WHERE revenueSourcemetadata = 'new'
AND Status = 'Paid'
GROUP BY mantaSubscriptionIdmetadata, planIdmetadata, RevenueGenerated
)a
JOIN (
SELECT id, Name, Interval
FROM [sample_internal_data.subplans]
WHERE id IN ('150017','150030','150033','150019')
GROUP BY id, Name, Interval
)b
ON a.planIdmetadata = b.id
GROUP BY ID, Interval, Name
ORDER BY Interval ASC

I want a case statetement that count more than 1 as 1

Please help solve the below query.
The column in question has Y and N and I want the N to show zero and the Y to show 1.
I want it to aggregate the no of times visited for each machine and if >= 1 to show 1. Client requirement is whether machine has been visited regardless of the number of times.
Select MachineNo,
[Date_of_Visit],
Month([Date_of_Visit])[Month],
Year([Date_of_Visit])[Year],
sum(case when [Visited] = 'Y' then 1 else 0 end)[No of Visits]
FROM [MachineVisit]
Group by [Date_of_Visit],
[MachineNo]
Use Max instead of Sum
Max(case when [Visited] = 'Y' then 1 else 0 end)[Visits]
This is a little confusing, the way it is written, but I am assuming you want something like:
select sum(case when [visited] >1 then 1 else null end) visists
from visit_table
where visit_date = '2015-01-30'
This is assuming that you have a table that counts the visits for a single day for 1 IP address as single entry.
If you have a table that has an entry for every single page visit, then you would probably need to do:
select count(distinct ip_address)
from (
select ip_address
from visit_table
where visit_date = '2015-01-30'
group by ip_address
having count(1) >1
) x
EDIT:
Well then the simplist way should be:
select count(1)
from visit_table
where [visited]='Y'
and visit_date = '2015-01-30'
;
That should work...
Although I don't have the table in front of me - so if this doesn't work, please post the fully query.