Calculated value in another column - mysql

I have a table that has 4 column that needs to be calculated to get the average value. I know how to get the average value.
What I don't know how to do is to get get that value to show on another column on another table. How do I do that?
Example:
Columns: ID Size1 Size2 Size3 Size4
Values: 1 92 82 63 83
I know how to get the average value from that, but I need to know how a column in another table can refer to that average value. I am using PHPMyAdmin

Has stated in the comments if you just need this as a query result a join will do.
Select t1.ID,t2.ID,(T1.Size1 + T1.Size2 + T1.Size3 + T1.Size4) / 4 as Avg
From t1 join t2 on t1.ID = t2.ID;
This assumes that T1 is table one (has sizes) and T2 is the second table in which you have the other values that you want to add average to.
Now lets assume you want an avg column in another table to be tied to rows in your T1 (sizes) table. To do this you can use a trigger.
CREATE TRIGGER AvgValues
ON T1
AFTER INSERT
AS
BEGIN
INSERT INTO T2(Avg)
SELECT (T1.Size1 + T1.Size2 + T1.Size3 + T1.Size4) / 4
FROM T1
WHERE T1.ID = T2.ID
END

Related

Compare field in single row to entire column

I have a column of dates, and I would like to have a second column that tallies the total amount of times a date in the first column shows up over the whole column. I am trying to use Count(IIf(...)), but I don't know how to specify that SSRS use the current row as the standard, and then check the whole column for the count.
Dates Records
9/14/18 2
9/14/18 2
9/15/18 1
9/16/18 3
9/16/18 3
9/16/18 3
Assuming you are not using a very old version of SQL Server then you could just do something simple like
SELECT
*
, COUNT(*) OVER(PARTITION BY PartTran_TranDate) AS DateCount
FROM myTable
Perhaps this will help. I changed it up a little bit for simplicity:
DECLARE #Table TABLE (DateCol DATE)
INSERT #Table
VALUES ('9/14/18'),
('9/14/18'),
('9/15/18'),
('9/16/18'),
('9/16/18'),
('9/16/18')
SELECT t.DateCol, r.rn
FROM #Table t
OUTER APPLY (SELECT COUNT(DateCol) rn
FROM #Table t2
WHERE t2.DateCol = t.DateCol
GROUP BY t2.DateCol) r

How to merge two Dataset/Table using Joins or any other operations in Python or SQL

I have two tables/Datasets. 1st table consists of 3 rows and the 2nd table consists of 97 rows.
I need to merge both these datasets/tables, so i get a final output of 100 rows in a table/dataset.
I tried using, Inner Join, Full outer Join. But none are giving me the required result.
Please let me know, what Joins or Operations I can use using either SQL or Python Script.
Timestamp kW_System Anomaly score Alert indicator
2016-09-08T07:17:07Z 174.877105 1.455553 1
2016-09-13T09:32:07Z 175.462994 0.952738 1
2017-01-14T23:03:07Z 181.580188 1.057076 1
Timestamp kW_System Anomaly score Alert indicator
2016-09-14T21:33:07Z 0 1.056694 1
2016-09-14T22:03:07Z 0 1.226853 1
2016-09-14T22:33:07Z 0 1.265696 1
.
.
.
.
.
.
2016-12-17T05:48:07Z 2.10767 2.599405 1
2016-12-17T06:18:07Z 2.306138 1.370845 1
2016-12-17T07:18:07Z 2.089892 1.887742 1
You should use UNION operator (or UNION ALL if you don't want to remove duplicate row)
SELECT * FROM 1st table
UNION
SELECT * FROM 2nd table
Assuming you want them gathered into a new table, create the new table like so:
CREATE TABLE new_tbl LIKE orig_tbl1;
Then insert the data from your two tables:
INSERT INTO new_tbl SELECT * FROM orig_tbl1;
INSERT INTO new_tbl SELECT * FROM orig_tbl2;
If you want to collect all the rows in one of your existing tables, just adapt the insert statement like so:
INSERT INTO orig_tbl1 SELECT * FROM orig_tbl2;
This should work in MySQL. There will be very similar statements in most other database systems.
We can emulate it by doing a UNION of a left join and a right join, like this:
-- t1 left join t2
SELECT * FROM t1 LEFT JOIN t2
UNION ALL -- include duplicates
-- t1 right exclude join t2 (records found only in t2)
SELECT * FROM t1 RIGHT JOIN t2;

How to get return value of two days price in one SQL statement in SQL Server 2008

I have Table like this
create table #tmp(dt Date, price float)
insert into #tmp values('01-Jan-2013', 55.60)
insert into #tmp values('02-Jan-2013', 50.22)
insert into #tmp values('03-Jan-2013', 52.00)
insert into #tmp values('04-Jan-2013', 55.90)
insert into #tmp values('05-Jan-2013', 60.60)
select * from #tmp order by dt
drop table #tmp
I want to get return value of two days price in one SQL statement. Calculation is simple, for example if I want to Calculate Return value of Date 02-Jan-2013 is: price value of 02-Jan-2013 divide by price value of 01-Jan-2013 and -1.
I want a output like the bellow
dt |price |Return
-------------------------------------
01-Jan-2013 |55.6 |0
-------------------------------------
02-Jan-2013 |50.22 |-0.09676259
-------------------------------------
03-Jan-2013 |52 |0.035444046
-------------------------------------
04-Jan-2013 |55.9 |0.075
-------------------------------------
05-Jan-2013 |60.6 |0.084078712
How Can I get the result whithin a single SQL Statement?
Seems fairly straightforward:
select
t1.dt,t1.price,
(t1.price/t2.price)-1 as [return]
from
#tmp t1
left join
#tmp t2
on t1.dt = DATEADD(day,1,t2.dt)
Note that this currently returns NULL for the first row rather than 0, but that could be fixed by wrapping the calculation in a COALESCE(...,0) if required. Note, also, that this assumes that there are values for every day. If that's not so, we need a more complex query.
If you need to allow for missing dates, you're going to have to pay a price for a significantly slower query:
select
t1.dt,t1.price,
(t1.price/t2.price)-1 as [return]
from
#tmp t1
left join
#tmp t2
on t2.dt < t1.dt
left join
#tmp t3
on t3.dt < t1.dt and
t2.dt < t3.dt
where
t3.dt is null
Ignoring for the moment that all these rows are coming from the same table, what we're basically saying is to pair the t1 rows with any t2 rows which occur before the t1 rows. We then try to find (via t3) any rows which occur after the t2 rows, but still before the t1 rows. Only if we cannot locate a t3 row is the t2 row the one we wanted - it's the latest possible previous row. Sorry if that sounds convoluted, always searching for a better way to explain this.

Increment value upto missing consicutive numbers

I have a table with a field have values 1,2,3,5,6,....
My problem is,When i try to insert "2" current 2,3 are incremented with 1 and 5,6 remains unchanged(because 4 is not exist),Then in the place of 2 new value needs to be inserted.
I try update query with
Update table set v1=v1+1 where v1>=newvalue
before insert a new value.But 5,6 also incremented with 1.I dont know how to do this.Does anyone know how to handle this ,Please help me.I have large amount of data,so not possible to make loop for update each value
SELECT t1.v1 + 1 AS gap
FROM `table` AS t1
LEFT OUTER JOIN `table` AS t2 ON t2.v1 = t1.v1 + 1
WHERE t2.v1 IS NULL AND t1.v1 >= :newvalue
ORDER BY t1.v1 ASC
LIMIT 1
This query gives the upper bound for updating v1 when inserting :newvalue.

Swap column value with the same column of another record

I have this fairly straightforward table with ID, Position, Name columns.
ID Position Name
1 1 RecordX
2 3 RecordY
3 2 RecordZ
The Position column serves as an index for displaying the records in a user defined order, it should be unique, can not be lower than 1 and not be higher than the number of records in the table, in this case 3. The column doesn't enforce uniqueness so temporarily there can be 2 records with the same Position, but eventually no two records should have the same position for the correct working of the program.
Currently, in order to swap the position of two records I need to do 3 queries, namely:
find the other record's ID
update the current record's Position to match the other record's Position
update the other record's Position by it's previously found ID (Since momentarily there will be two records with the same Position, updating by Position is not possible.
I feel there should be a way to do this with less rounds to the database, and thus with less than 3 queries. How should I approach this problem?
Single "swap" operation...
SWAP(#old_pos, #new_pos)
UPDATE
my_table
SET
position = CASE WHEN position = #old_pos THEN #new_pos ELSE #old_pos END
WHERE
position IN (#old_pos, #new_pos)
This doesn't easily expand to a table of swap-operations though. This is because it will try to do all the swaps at once, when in fact the swaps must happen in a specific order...
Also, if you want to do SWAP(#id, #new_pos) you need to either do a sub-query or self join on the table you are updating. MySQL doesn't like that, and although there are ways around the limitation, it makes things get a bit messy...
UPDATE
my_table
INNER JOIN
(SELECT position AS old_pos, #new_pos AS new_pos FROM (SELECT position FROM my_table WHERE id = #id)) AS params
ON my_table.position IN (params.old_pos, params.new_pos)
SET
myTable.position = CASE WHEN position = old_pos THEN new_pos ELSE old_pos END
(I think that will work)
NOTE:
Both of these assume that BOTH #old_pos and #new_pos, or #id and #new_pos are found, it doesn't check, and will make a mess if they don't exist.
This can be resolved by putting it in a transaction, and rolling back if ROW_COUNT() shows that only 1 record is updated.
SET #new_pos_for_id_1:=3, #new_pos_for_id_3:=1;
UPDATE my_table
JOIN (
SELECT 1 as id, #new_pos_for_id_1 as new_position
UNION ALL
SELECT 3 as id, #new_pos_for_id_3 as new_position) as positions
USING (id)
SET position = new_position
This query can be used to change positions for several rows at a time. I like the #Dems' solution as well.
UPD:
Explanation
SELECT 1 as id, 3 as new_position
UNION ALL
SELECT 3 as id, 1 as new_position
is a on-fly constructed table of two columns: id, new_position where each id is mapped to some new intended position. THen I just JOIN the table with my_table on the common id field and substitute values in my_table with values from the constructed table.
This will probably work for any DBMS.
-- create some data
DROP TABLE ztable CASCADE;
CREATE TABLE ztable
( id integer NOT NULL PRIMARY KEY
, val INTEGER
);
INSERT INTO ztable(id,val) VALUES (1,1), (2,3), (3,2);
SELECT * FROM ztable;
UPDATE ztable t1
SET val=t2.val
FROM ztable t2
WHERE t1.id IN (2,3)
AND t2.id IN (2,3)
AND t1.id <> t2.id
;
SELECT * FROM ztable;
Results:
CREATE TABLE
INSERT 0 3
id | val
----+-----
1 | 1
2 | 3
3 | 2
(3 rows)
UPDATE 2
id | val
----+-----
1 | 1
2 | 2
3 | 3
(3 rows)