Set one row fields as a multiplication of 2 others - sql

I have a such a structure of SQL table
Id A B C D
1 1 5 6 25
2 2 10 5 25
3 3 7 4 25
4 1 6 5 26
5 2 10 5 26
6 3 8 3 26
I want to write a script, which will update all the B & C columns in the rows with A=3 with the value of multiplication of the A = 1 and A = 2 (for the same value of D column)
So the result should be
Id A B C D
1 1 5 6 25
2 2 10 5 25
3 3 50 30 25
4 1 6 5 26
5 2 10 5 26
6 3 60 25 26
How can I write such a code in SQL?

One possible way is joining table to itself twice:
update T3
set
T3.B = T1.B * T2.B,
T3.C = T1.C * T2.C
from [Table] T3
join [Table] T1 on T1.A = 1 and T1.D = T3.D
join [Table] T2 on T2.A = 2 and T2.D = T3.D
where
T3.A = 3

Related

How do I add specific columns from different tables onto an existing table in postgresql?

I have an original table (TABLE 1):
A
B
C
D
1
3
5
7
2
4
6
8
I want to add column F from the table below (Table 2) onto table 1:
A
F
G
H
1
29
5
7
2
30
6
8
As well as adding Column J,L and O from the table below (Table 3) onto column 1:
A
I
J
K
L
M
N
O
1
9
11
13
15
17
19
21
2
10
12
14
16
18
20
22
How do I go about adding only the specific columns onto table 1?
Expected Result:
A
B
C
D
F
J
L
O
1
3
5
7
29
11
15
21
2
4
6
8
30
12
16
22
Use following query
SELECT T1.A,
B,
C,
D,
F,
J,
L,
O
FROM table1 T1
JOIN table2 T2
ON T1.A = T2.A
JOIN table3 t3
ON T1.A = T3.A

Update rows based on range around values without changing rows that are not initially within range

In a local SQLite (vs 3.29.0) database, there is a table with 3 columns (excluding the rowID). Two contain values, and one contains categories. I want to update the category based on a range around the values of one specific category. It needs to be possible that the category that is SET is the same category as the one that determines the range.
Example:
id
Value
Value2
Category
1
20
20
2
2
30
30
2
3
40
40
2
4
70
70
2
5
5
5
1
6
19
19
1
7
26
26
1
8
42
42
1
9
49
49
1
10
52
52
1
11
71
71
1
12
90
90
1
13
17
17
1
I want rows to be changed to category 2, based on a range of 4 around value and a range of 2 around value2. This should change only rows 6, 9 and 11:
id
Value
Value2
Category
1
20
20
2
2
30
30
2
3
40
40
2
4
70
70
2
5
5
5
1
6
19
19
2
7
26
26
1
8
42
42
2
9
49
49
1
10
52
52
1
11
71
71
2
12
90
90
1
13
17
17
1
My current SQL statement is:
UPDATE tablename
SET Category = 2
WHERE (Category != 2
AND EXISTS (
SELECT *
FROM tablename t
WHERE t.Category = 2
AND tablename.Value BETWEEN t.Value - 4 AND t.Value + 4
AND tablename.Value2 BETWEEN t.Value2 -2 AND t.Value2 +2)
);
of which the result is:
id
Value
Value2
Category
1
20
20
2
2
30
30
2
3
40
40
2
4
70
70
2
5
5
5
1
6
19
19
2
7
26
26
1
8
42
42
2
9
49
49
1
10
52
52
1
11
71
71
2
12
90
90
1
13
17
17
2
What appears to be happening is that due to row 6 changing to category 2, row 13 is now within range of the values of a row that is in category 2, and therefore is also assigned category 2. How do I change the statement so that the SET is only applied to the values that were within range initially?
See the demo for the example.
If your version of SQLite is 3.33.0+ you can use the join-like UPDATE...FROM syntax to perform a self join in the UPDATE statement:
UPDATE tablename AS t1
SET Category = t2.Category
FROM tablename AS t2
WHERE t2.Category = 2
AND t1.Category <> t2.Category
AND t1.Value BETWEEN t2.Value - 4 AND t2.Value + 4
AND t1.Value2 BETWEEN t2.Value2 - 2 AND t2.Value2 + 2;
For previous versions of SQLite, first create a temporary table with all the rows of the table with Category = 2:
CREATE TEMPORARY TABLE t AS
SELECT * FROM tablename WHERE Category = 2;
and then update the table:
UPDATE tablename
SET Category = 2
WHERE Category <> 2
AND EXISTS (
SELECT 1
FROM t
WHERE tablename.Value BETWEEN t.Value - 4 AND t.Value + 4
AND tablename.Value2 BETWEEN t.Value2 -2 AND t.Value2 + 2
);
See the demo.

Get result using two tables without using any loop

I have two tables Temp_Test and Temp_Marks.
Temp_Test is having following columns
id UserId QId QTitle QMarks
1 A1 1 A 5
2 A1 2 B 6
3 A1 3 C 4
4 A1 4 D 5
5 B3 1 A 8
6 B3 2 B 6
7 B3 3 C 4
8 B3 4 D 3
9 Z9 1 A 2
10 Z9 2 B 7
11 Z9 3 C 9
12 Z9 4 D 3
and Temp_Marks has following Columns
Id Score A B C D
1 1 10 5 40 12
2 2 20 10 50 23
3 3 30 15 60 34
4 4 40 20 70 54
5 5 50 25 80 84
6 6 60 30 90 36
7 7 70 35 10 85
8 8 80 40 20 97
9 9 90 45 30 58
10 10 100 50 100 48
I want to fetch result of particular UserId.
eg. If for A1, QTitle is A and marks is 5 in Temp_test table then fetch record from Column A where Score is 5 from Temp_Marks table.
without using while loop want to fetch all records of particular UserId or UserIds.
Can anyone help on this?
You may want to UNPIVOT the Temp_Marks first to easily join it with Temp_Test, and then PIVOT the result to achieve the desired format:
;WITH CteUnpivotedMarks AS(
SELECT
ID, Score, Col = 'A', Value = A
FROM Temp_Marks
UNION ALL
SELECT
ID, Score, Col = 'B', Value = B
FROM Temp_Marks
UNION ALL
SELECT
ID, Score, Col = 'C', Value = C
FROM Temp_Marks
UNION ALL
SELECT
ID, Score, Col = 'D', Value = D
FROM Temp_Marks
)
SELECT
UserId = t.UserID,
A = MAX(CASE WHEN t.QTitle = 'A' THEN c.Value END),
B = MAX(CASE WHEN t.QTitle = 'B' THEN c.Value END),
C = MAX(CASE WHEN t.QTitle = 'C' THEN c.Value END),
D = MAX(CASE WHEN t.QTitle = 'D' THEN c.Value END)
FROM Temp_Test t
INNER JOIN CteUnpivotedMarks c
ON t.QTitle = c.Col
AND t.QMarks = c.Score
GROUP BY t.UserID
RESULT
UserId A B C D
---------- ----------- ----------- ----------- -----------
A1 50 30 70 84
B3 80 30 70 34
Z9 20 35 30 34

Case statements on where clause?

I am a bit new to case statements but below is my query.
Table1
col1 col2 col3 col4 Month Freeze
1 13 25 37 1 0
3 15 27 39 2 1
4 16 28 40 2 0
5 17 29 41 3 1
6 18 30 42 3 0
7 19 31 43 4 1
8 20 32 44 4 0
9 21 33 45 5 1
10 22 34 46 5 0
11 23 35 47 6 0
'Results i want like':
Select all records from Month1 to Month 12 where 'Freeze = 1' ,
if any month between 1 to 12 does not have Freeze = 1 then give me records for Freeze= 0 'just for the months which does not have 'Freeze = 1'
My best non-working attempt:
select * from tb1 where Month between 2 and 6 and freeze = 1 or Month in ('1' ,'2') and freeze = 0
Here is one option using an outer join:
select t1.*
from Table1 t1
left join Table1 t2 on
t1.month = t2.month and t2.freeze = 1
where t1.freeze = 1
and t1.month between 1 and 12
or t2.month is null
SQL Fiddle Demo
Results:
COL1 COL2 COL3 COL4 MONTH FREEZE
1 13 25 37 1 0
3 15 27 39 2 1
5 17 29 41 3 1
7 19 31 43 4 1
9 21 33 45 5 1
11 23 35 47 6 0
Note, depending on your data, you may need to use distinct with this method.
The following is a method that uses standard SQL:
Select t1.*
from table1 t1
where Freeze = 1 and month between 1 and 12 or
(not exists (select 1 from table where Freeze = 1 and month between 1 and 12) and
month = 0
);
Using window functions, you could also do:
select t1.*
from (select t1.*,
count(case when freeze = 1 and month between 1 and 2) over () as freeze1cnt
from table1 t1
) t1
where month between 1 and 2 and freeze = 1 or
month = 0 and freeze1cnt = 0;

Find multiple records with same Id in SQL server

Find multiple records with same Id in SQL server
I have following value in my table
PK Id Value1 Value2
1 1 5 10
2 1 10 10
3 2 5 20
4 3 20 25
5 3 5 5
6 4 10 10
7 1 5 20
8 4 5 10
9 2 25 30
10 5 25 30
11 5 5 20
12 5 5 5
I want to get 'Id' column which have two record with some values like (First Record) Value1 = 5, Value2 = 20 and (Second Record) Value1 =25, Value2 = 30.
In Above table my expected result is
PIds Id Value1 Value2
3 2 5 20
9 2 25 30
10 5 25 30
11 5 5 20
Thanks in Advance.
Please try:
select * from YourTable
where
(Value1=5 and Value2=20) OR
(Value1 =25 and Value2 = 30)
All other query shows 1, 2 and 5 Ids
I have found this query for my problem
select T1.Id,* from TestData T1 inner join TestData T2
on T1.Id = T2.Id
where
(T2.Value1=5 and T2.Value2=20) and
(T1.Value1=25 and T1.Value2 = 30)