Trying to resolve three conditions for a bit column - tsql

Good Morning,
Seems like this shouldn't be hard to do but my TSQL knowledge is lacking. How do I resolve three conditions for a bit column? This is what I have but of course the compiler doesn't like the OR in the CASE.
To be clear a in the case of All I want both zero and one column values. Null will be excluded.
MyTable
Id Name LockedState Deleted
12 Doe, John 0 1
14 Doe, Johnny 0 1
15 Fischer, Julia 1 1
16 Hemsworth, Christopher 0 1
17 Getty, Kristyn 1 1
SELECT *
FROM MyTable
WHERE Deleted = #Deleted
AND LockState = CASE
WHEN #Assigned = 'ALL' THEN 0 OR 1
WHEN #Assigned = 'Assigned' THEN 1
WHEN #Assigned = 'UnAssigned' THEN 0
END
Desired Output for 'All'
12 Doe, John 0 1
14 Doe, Johnny 0 1
15 Fischer, Julia 1 1
16 Hemsworth, Christopher 0 1
17 Getty, Kristyn 1 1
Desired Output for 'Assigned'
15 Fischer, Julia 1 1
17 Getty, Kristyn 1 1
Desired Output for 'Unassigned'
12 Doe, John 0 1
14 Doe, Johnny 0 1
16 Hemsworth, Christopher 0 1

You can use something like this:
SELECT *
FROM MyTable
WHERE Deleted = #Deleted
AND (#Assigned = 'Assigned' AND LockState = 1
OR #Assigned = 'UnAssigned' AND LockState = 0
OR #Assigned = 'ALL')
or like this:
SELECT *
FROM MyTable
WHERE Deleted = #Deleted
AND LockState = CASE
WHEN #Assigned = 'ALL' THEN LockState
WHEN #Assigned = 'Assigned' THEN 1
WHEN #Assigned = 'UnAssigned' THEN 0
END

Related

query customer retention over range

I am trying to find the best way to accomplish the following.
Get the beginning customer count, which carries from the previous day
Get New Customer count
Get the number of Customers who have not come in since the prior month
Get the number of Customers who have come back after lapsing
Get the number of total customers
The following example
Customer ID
Store ID
Date
Amount
1
1
1/2/22
1.00
2
2
1/2/22
2.00
1
1
2/2/22
1.00
3
2
3/2/22
1.00
2
2
3/2/22
1.00
1
1
3/2/22
1.00
1
1
4/2/22
1.00
4
1
4/2/22
1.00
2
2
4/2/22
1.00
The result would be
Date
Store
Beginning
New
Dropped
Returned
Total
1/2/22
1
0
1
0
0
1
1/2/22
2
0
1
0
0
1
2/2/22
1
1
0
0
0
1
2/2/22
2
1
0
1
0
0
3/2/22
1
1
0
0
0
1
3/2/22
2
0
1
0
1
2
4/2/22
1
1
1
0
0
2
4/2/22
2
2
0
1
0
1
I kind of have a query, but it's not getting the right results
WITH customerset AS (
SELECT
location_id,
date,
array_agg(DISTINCT customer_id ORDER BY customer_id ASC) AS customer_ids
FROM customer_orders
GROUP BY
location_id,
date
)
SELECT
cset.location_id,
cset.date,
array_length(cset2.customer_ids, 1) AS beginning,
array_length((past2.customer_ids - cset.customer_ids), 1) AS dropped,
array_length((cset.customer_ids - past2.customer_ids), 1) AS returned
FROM
(
SELECT
ords.location_id,
ords.date,
array_agg(DISTINCT ords.customer_id ORDER BY ords.customer_id ASC) AS customers_id
FROM customer_orders ords
GROUP BY
ords.location_id,
ords.date
) cset
JOIN
customerset cset2 ON cset.date - '1 month'::interval = cset2.date
AND cset2.location_id = cset.location_id
GROUP BY
cset.location_id,
cset.date,
cset2.customer_ids,
cset.customer_ids
ORDER BY
cset.date ASC

Recursive Cumulative Sum up to a certain value Postgres

I have my data that looks like this:
user_id touchpoint_number days_difference
1 1 5
1 2 20
1 3 25
1 4 10
2 1 2
2 2 30
2 3 4
I would like to create one more column that would create a cumulative sum of the days_difference, partitioned by user_id, but would reset whenever the value reaches 30 and starts counting from 0. I have been trying to do it, but I couldn't figure it out how to do it in PostgreSQL, because it has to be recursive.
The outcome I would like to have would be something like:
user_id touchpoint_number days_difference cum_sum_upto30
1 1 5 5
1 2 20 25
1 3 25 0 --- new count all over again
1 4 10 10
2 1 2 2
2 2 30 0 --- new count all over again
2 3 4 4
Do you have any cool ideas how this could be done?
This should do what you want:
with cte as (
select t.a, t.b, t.c, t.c as sumc
from t
where b = 1
union all
select t.a, t.b, t.c,
(case when t.c + cte.sumc > 30 then 0 else t.c + cte.sumc end)
from t join
cte
on t.b = cte.b + 1 and t.a = cte.a
)
select *
from cte
order by a, b;
Here is a rextester.

How do I transpose columns into rows using tree in SQL? Is there any tree in sql command to transpose?

We are trying to output for each customer column should have 12 budgeted row entries for every month.
Scenario 1:
ie. Turn table data :
Name BudMnt1|BudMnt2|BudMnt3
cust1 0 0 0
cust2 0 0 0
cust3 2418 0 0
cust4 0 416 198
into this :
Name cust1| cust2| cust3| cust4
BudMnt1 0 0 24180 0
BudMnt2 0 0 0 416
BudMnt3 0 0 0 198
Scenario 2:
Includes Scenario 1 column as Budget+ additional column is sales solumn here
so, it becomes two column budget ,sales which needs to unpivot on single query structure.
ie. Turn table data :
Name JanSales|FebSales|MarSales
cust1 0 0 0
cust2 0 0 0
cust3 0 0 3
cust4 2 0 0
into this :
Name cust1|cust2|cust3|cust4
JanSales 0 0 0 2
Feb Sales 0 0 0 0
Mar Sales 0 0 3 0
Any HELP would be much appreciated !
This link may help you as a reference to your question:
https://social.msdn.microsoft.com/Forums/office/en-US/04346f7c-0923-432d-83c3-22bf759dea22/transpose-data-from-columns-into-rows-using-sql
This code works fine. Tasted it on sql server 2012.
SELECT NAME ,
budmtn ,
cust
INTO #temptable
FROM ( SELECT *
FROM tbl1
) AS result UNPIVOT ( cust FOR budmtn IN ( budmtn1, budmtn2, budmtn3 ) ) AS unpivotedtable
SELECT budmtn ,
cust1 ,
cust2 ,
cust3 ,
cust4
FROM #temptable PIVOT( SUM(cust) FOR NAME IN ( cust1, cust2, cust3, cust4 ) ) AS result

how to write one sql to update data?

Suppose I have data in table like:
id level flag
1 1 0
1 2 0
1 3 1
1 4 0
1 5 1
1 6 0
1 7 0
1 8 1
1 9 1
1 10 0
2 1 0
2 2 0
2 3 0
2 4 0
2 5 1
2 6 1
2 7 1
......
I want to update flag to 0 after first 1 value for flag. For example, with above sample data,
for id = 1, the first flag value =1 is level=3, then all flag values for level>3 should be updated to 0.
For id = 2, should update flag = 0 for all level>5
How to implement it with sql even one sql statement?
You should be able to do this with a WHERE EXISTS on the same table:
UPDATE t1
SET flag = 0
FROM TheTable t1
WHERE EXISTS (
SELECT 1
FROM TheTable t2
WHERE t2.id = t1.id
AND t2.level < t1.level
AND t2.flag = 1
)
SQL Fiddle demo
You can do this with an exists statement:
update table t
set flag = 0
where exists (select 1
from table t2
where t2.id = t.id and
t2.level < t.level and
t2.flag = 1
);

Reorder Ranked rows

Recently i needed to implement a way to allow for Table Records to be Ranked.
Initially i deployed an Update statement to seed the ranks:
;with cte as (
select
t.id,
Rank() Over (
Partition by t.field2
Order by t.id
) as [Rank],
t.index,
t.field2,
t.field3 ,
t.field4
from dbo.Table t
where t.field2 = #fldValue
) Update cte
set index = [Rank]
But now i need to be able to have the end-user re-order the ranks. Any suggestions on how to allow an end-user to take Rank value 92 to Rank value 15 and have everything be re-ranked appropriately.
I had thought about doing this via cursor but am trying to do this via Set based operation.
My first goto was to do a Procedural based operation but need to get more inline with Set based operation.
Table Schema
Table:
id bigint
field2 int
field3 int ---> This field will be the key pivoting column for ranking
field4 int
Data:
id field2 field3 field4
1 0 1 1
2 0 1 1
3 0 1 1
4 0 1 2
5 0 1 2
6 0 1 1
7 0 1 1
8 0 1 1
9 0 1 1
10 0 1 2
11 0 1 2
12 0 1 1
13 0 1 1
14 0 1 1
15 0 1 2
16 0 1 1
17 0 1 2
18 0 1 2
19 0 1 1