How to update the value of a column after Select statement - sql

I have following table and when I run the following query , select * from mytable , I get following result.
Column 1 Value 1
--------------------------------------
Row 1 1
Row 2 0
Row 3 1
Row 4 0
Row 5 1
Row 6 0
But I need all the values to 0, no matter if it's 1 or 0. So the representation would be something like this.
Column 1 Value 1
--------------------------------------
Row 1 0
Row 2 0
Row 3 0
Row 4 0
Row 5 0
Row 6 0
I can create a table variable and then go ahead and updte the records after inserting to it, but is there any other way?

select Column1, '0' as Value1 from mytable

UPDATE mytable SET [Value 1] = 0
Will change the value for all rows. But I have a feeling there is more to your question. Can you explain why you need the Value 1 field changed after the SELECT?
If you want all the Column 1 rows with a zero for Value 1, change your SELECT:
SELECT Column1, '0' [Value 1] FROM mytable

Related

SQL get count of value

I have the following table. Now I want to count the amount of each value in this table.
value
count
1
1
-1
1
2
1
3
1
-1 and 1 should be seen as 1, so the output should be
value
count
1
2
2
1
3
1
Does someone know a quick fix?
Grouping by value, and making such values the absolute value so you ignore the negative sign:
SELECT
ABS(VALUE) VALUE, COUNT() COUNT
FROM
table
GROUP BY
ABS(VALUE)

Create a column with Conditional Recursive SQL / based on a condition

Consider the table ordered by id with column IsSatisfied.
ID
IsSatisfied
1
0
2
1
3
0
4
0
5
1
6
0
....
...
I would like to create another column State, that initially takes value 0 and changes it between 0 and 1, only when the value of Isatisfied is equal to 1, as in the table below.
ID
IsSatisfied
State
1
0
0
2
1
1
3
0
1
4
0
1
5
1
0
6
0
0
....
...
...
I tried LAG() function or recursive CTE, but unfortunately failed.
The closest solution that I have found is Conditional Recursive SQL Select, but I was not able to convert it to suit my needs.
If I understand correctly, you want a cumulative sum of issatisfied -- and then the remainder when divided by 2:
select t.*,
( sum(issatisfied) over (order by id) % 2 ) as state
from t;

Update Table at fixed interval of Time SQL Server

I have a table with 3 Columns: ID, Date and ColA
I want to write a Sql query which will update ColA with a value from another Table only after every 3 days else ColA value should be 0.
The Query should be grouped by ID.
Table 1
ID Date ColA
1 2020/01/01 0
1 2020/01/02 0
1 2020/01/03 Run Update Query
1 2020/01/04 0
1 2020/01/05 0
1 2020/01/06 Run Update Query
2 2020/02/09 0
2 2020/02/10 0
2 2020/02/11 Run Update Query
2 2020/02/12 0
2 2020/02/13 0
2 2020/02/14 Run Update Query
Any ideas?? Thanks
You can use window functions:
with cte as (
select colA, row_number() over(partition by id order by date) rn
from mytable
)
update cte
set colA = case when rn % 3 = 0 then 'Run update query' else '0' end
The common table expression(aliasedcte) ranks records having the same id by increasing date. Then, the outer query assigns the correct value depending on the rank.

How to add sequence number to group of rows based on status column

I have a group of rows in order. Column "Status" has only two value 0/1. Now, I'd like to add a sequence number / group number for each 0/1 set. there can be 1 to many rows of 0's but only one 1 for each set in the end. How do I add a new column as sequence number that only increases when there is a 1.
example:
ID Status Row Group Number
1 0 1
2 0 1
3 1 1
4 0 2
5 1 2
6 0 3
7 0 3
8 0 3
9 1 3
question is how do I get the third column?
thank you.
Hmmm . . . This is a cumulative sum up to the previous row (plus 1). So, in SQL Server 2012+, you can do:
select t.*,
1 + sum(status) over (order by id) - status as rowgroupnumber
from t;

SQL Server Conditional filtering

I essentially would like to execute a statement where x=1 AND a=2. If a<>2 then return results for filter x=1.
I've tried OR statement but it ignores my a=2 filter if there is a scenario where a does equal 2. Example below
select *
from dbo.test
where (x=1 and a=2)
or
x=1
For output purposes below: type = x and Id = a
Expected result when Type = 1.
Id(a) Name Person Type(x)
2 a Mike 1
7 b Jim 1
3 c Tom 1
4 d Tim 1
5 e Dave 1
Expected result when Type = 1 and Id = 2
Id(a) Name Person Type(x)
2 a Mike 1
Expected result when Type = 1 and Id <> 2 (scenario when there is no '2' in Id column)
Id(a) Name Person Type(x)
8 a Mike 1
7 b Jim 1
3 c Tom 1
4 d Tim 1
5 e Dave 1
The issue is not when Id = 2. It is returning Type = 1 when Id <> 2. Does that mean a case statement?
select *
from dbo.test
where (x=1 and a=2)
or x=1
Is the same as:
select *
from dbo.test
where x=1
AND requires both conditions be met, and OR requires one condition to be met. The value of a is irrelevant.
UPDATE:
You can get what you're after using the RANK() function in conjunction with a CASE statement:
;WITH cte AS (SELECT *,RANK() OVER(ORDER BY CASE WHEN id = 2 THEN 1 ELSE 2 END)RNK
FROM Table1
WHERE Type = 1)
SELECT *
FROM cte
WHERE RNK = 1
If id = 2 is present in the table, only that record will be returned, otherwise all records will be returned.
Demo: SQL Fiddle
I'm guessing that you want to return a single row.
insert into test(x,a,v) values (0, 0, 'No good')
insert into test(x,a,v) values (1, 0, 'OK')
insert into test(x,a,v) values (1, 2, 'Better')
You want the row that has x=1 a=2 if it is there
You want the row that has x=1 if there is none better
You want nothing if there is no x=1 row
If that's the case then it is a bit tricky. You can score the rows using a CASE statement and then pick the row that has the best value. This may give you more than one row back if there is a tie.
SELECT v
FROM test
WHERE CASE WHEN x=1 AND a=2 THEN 1000
WHEN x=1 AND a<>2 THEN 100
ELSE 0 END =
(SELECT MAX(CASE WHEN x=1 AND a=2 THEN 1000
WHEN x=1 AND a<>2 THEN 100
ELSE 0 END)
FROM test)