Pairwise swapping of rows in sql - sql

I have a device settings table with threshold types and values.
Let's say ThresholdType = 0 is Min and ThresholdType = 1 is Max
The initial table looks like this:
DeviceID ThresholdType ThresholdValue
1 0 5
1 1 10
2 0 15
2 1 20
3 0 21
3 1 34
4 0 1
4 1 8
Then I had to change ThresholdType meaning - 0 became Max threshold and 1 became Min one.
I want the table look like that:
DeviceID ThresholdType ThresholdValue
1 0 10
1 1 5
2 0 20
2 1 15
3 0 34
3 1 21
4 0 8
4 1 1
Is it possible to change update it with a single SQL without loops?

Update ThresholdType instead:
update tablename set ThresholdType = 1 - ThresholdType
In case other ThresholdType values might show up later, you can add WHERE ThresholdType IN (1, 2), to be a bit safer.

Just swap the ThresholdType:
UPDATE t SET ThresholdType = CASE ThresholdType
WHEN 1 THEN 0
WHEN 0 THEN 1
ELSE ThresholdType
END
Execute the query exactly once.

You can do:
update t
set ThresholdValue = (
select x.ThresholdValue
from t x
where x.DeviceID = t.DeviceID and x.ThresholdType <> t.ThresholdType
)
Result:
DeviceID ThresholdType ThresholdValue
--------- -------------- --------------
1 0 10
1 1 5
2 0 20
2 1 15
See running example at db<>fiddle.

Related

SQLite computed column in WHERE clause seems to be working(?)

The order in which DMBS execute queries is:
FROM -> JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT
I was surprised to find out that this query works well on SQLite:
SELECT *, duration / 60 AS length_in_hours
FROM movies
WHERE length_in_hours > 10;
Why is this query working, while in some other cases it seems to fail?
OK, So I run EXPLAIN to see what's going on here.
.eqp full
PRAGMA vdbe_trace=true;
EXPLAIN
SELECT substr(name, 1, 1) AS initial
FROM names
WHERE initial = 'D';
The query results are:
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 11 0 0 Start at 11
1 OpenRead 0 7 0 2 0 root=7 iDb=0; names
2 Rewind 0 10 0 0
3 Column 0 1 2 0 r[2]=names.name
4 Function 6 2 1 substr(3) 0 r[1]=func(r[2..4])
5 Ne 5 9 1 80 if r[1]!=r[5] goto 9
6 Column 0 1 7 0 r[7]=names.name
7 Function 6 7 6 substr(3) 0 r[6]=func(r[7..9])
8 ResultRow 6 1 0 0 output=r[6]
9 Next 0 3 0 1
10 Halt 0 0 0 0
11 Transaction 0 0 10 0 1 usesStmtJournal=0
12 Integer 1 3 0 0 r[3]=1
13 Integer 1 4 0 0 r[4]=1
14 String8 0 5 0 D 0 r[5]='D'
15 Integer 1 8 0 0 r[8]=1
16 Integer 1 9 0 0 r[9]=1
17 Goto 0 1 0 0
In addr 0, the Init opcode sends us to addr 11 which open new Transaction.
Right after that SQLite allocate the integer 1 FOUR TIMES (addr 12-13, 15-16). That's where I started to suspect SQLite may artificially duplicate the expression before the AS into the WHERE clause.
In opcodes 3-5, which happen before the SELECT (opcodes 6-8), we can see that SQLite duplicated our substr into the WHERE clause.

Percent between two field PostgreSQL

I have 3 fields which are called game_series_count, game_series_wins and game_series_lost. I need to find wins percent.
select
"game_series_count",
"game_series_wins",
"game_series_lost",
round(( (game_series_wins / game_series_count) * 100), 1) as win_percent
from "statistic_teams"
but there is wrong result
game_series_count | game_series_wins | game_series_lost | win_percent
2 1 1 0
2 1 1 0
2 1 1 0
2 1 1 0
1 1 0 100
1 1 0 100
1 0 1 0
1 0 1 0
You are doing integer division. The simplest method for your purpose is probably:
round(game_series_wins * 100.0 / game_series_count, 1) as win_percent
Note that you can also economize on parentheses.

SQL update column depending on other column

sequenceNo IsPoint PointNumber PointSequenceNumber IsCancel
1 1 3168 1 1
2 0 NULL 2 1
3 1 3169 2 1
4 1 2806 3 1
5 1 33322 4 1
6 1 2807 5 1
7 1 2044 6 1
8 1 2046 7 1
9 0 NULL 8 1
10 1 27524 8 1
11 1 670 9 0
12 1 671 10 0
13 1 672 11 0
14 0 NULL 12 1
15 1 1074 12 1
16 1 10844 13 0
17 1 1421 14 0
I need to insert PointNumber to other table depending on value of IsCancel Column if IsCancel is set to 1 I need to insert first iscancel and last IsCancel but sequentially
e.g. STARTPOINT => above sequenceNo 1 for point number 3168 and Iscancel set to 1 I need that point to store in other table StartPoint
ENDPOINT => above sequenceNo 15 for point number 1074 and Iscancel set to 1 I need that point to store in other table as Endpoint
TotalCANCELED => Column hold COUNT IsCancel but only if PointNumber is not NULL
I need to update these columns in other table with following numbers depending on above table
STARTPOINT ENDPOINT TOTALCANCEL
3168 1074 9
Thanks community
I find this logic a bit hard to follow. If I understand this correctly, you can use aggregation -- although you need a little twist to get the end point number:
select max(case when PointSequenceNumber = 1 then pointnumber end) as startpoint,
max(case when PointSequenceNumber = psn then pointnumber end) as endpoint,
sum(case when isCancel = 1 and PointNumber is not null end) as totalCancel
from (select t.*,
max(case when isCancel = 1 and PointNumber is not null then PointSequenceNumber end) over () as max_psn
from t
) t;

SQL update by groups?

I'd like to update approximately the first X number of rows in a table but I want to always update all rows with a matching column at the same time. So if my table has:
MyID Transaction Amount Date Status
1 1 2 02/08/2016 0
1 1 4 02/08/2016 0
2 4 1 02/08/2016 0
2 3 2 02/08/2016 0
3 10 1 02/08/2016 0
3 6 4 02/08/2016 0
I want to update Status to 1 on approximately the first 5 rows, but I don't want to split up matching MyID values, how can I do that? I could update the first 4 or 6 in this example.
Here is one method:
update t
set status = 1
where myId in (select top 5 MyId from t order by MyId);

stored procedure to find value in 2 columns out of 3

I am putting in the samle date and i am supposed to do something similar what i am asking.
I want to run a query that would pull values in any two columns out 3 if it has a 1 or if any one column has a 1 it will return just those results. However it should search all three columns and in any of the three columns where it found value as 1 it should return that result. Can anyone please help me with this. Thanks in advance.
ID Patient Patient Name prio prio2 prio3
-------------------------------------------------
1 101563 Robert Riley 1 1 1
2 101583 Cody Ayers 1 0 1
3 101825 Jason Lawler 0 0 1
4 101984 Dustin Lumis 1 0 0
5 102365 Stacy smith 1 0 0
6 102564 Frank Milon 1 0 0
7 102692 Thomas Kroning 1 0 0
8 102856 Andrew Philips 1 0 0
9 102915 Alice Davies 0 0 1
10 103785 Jon Durley 0 0 1
11 103958 Clayton Folsom 1 1 1
12 104696 Michelle Holsley 1 1 1
13 104983 Teresa Jones 1 0 1
14 105892 Betsy Prat 1 1 0
15 106859 Casey Ayers 1 1 0
So, basically you want to pull anything where any of the 3 columns prio,prio2, or prio3 =1? Please clarify your question if this isn't what you are asking( for a better answer). Also, you should tag it with what type of SQL.
SELECT ID,Patient,[Patient Name],prio,prio2, prio3
FROM uRtable
WHERE prio = 1 OR prio2 = 1 OR prio3 = 1
But, if you are saying that you want to pull back any row where any of the 3 columns prio,prio2, or prio3 = 1, but at least one of them is 0 (Get any where any of the 3 = 1 but exclude where they all = 1), probably the easiest way to understand that would be
SELECT ID,Patient,[Patient Name],prio,prio2, prio3
FROM uRtable
WHERE (prio = 1 OR prio2 = 1 OR prio3 = 1)
AND (prio = 0 OR prio2 = 0 OR prio3 = 0)
Try this:
select * from mytable
where prio + prio2 + prio3 = (
select max(prio + prio2 + prio3)
from mytable
where prio = 1 or prio2 = 1 or prio3 = 1
)
SELECT *
FROM tbl
WHERE 1 IN (prio,prio2,prio3)