Average MySQL in new table - mysql-workbench

I have a database about weather that updates every second.
It contains temperature and wind speed.
This is my database:
CREATE TABLE `new_table`.`test` (
`id` INT(10) NOT NULL,
`date` DATETIME() NOT NULL,
`temperature` VARCHAR(25) NOT NULL,
`wind_speed` INT(10) NOT NULL,
`humidity` FLOAT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin;
I need to find the average temperature every hour.
This is my code:
Select SELECT AVG( temperature ), date
FROM new_table
GROUP BY HOUR ( date )
My coding is working but the problem is that I want to move the value and date of the average to another table.
This is the table:
CREATE TABLE `new_table.`table1` (
`idsea_state` INT(10) NOT NULL,
`dateavg` DATETIME() NOT NULL,
`avg_temperature` VARCHAR(25) NOT NULL,
PRIMARY KEY (`idsea_state`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin;
Is it possible? Can you give me the coding?

In order to insert new rows into a database based on data you have obtained from another table, you can do this by setting up an INSERT query targeting the destination table, then run a sub-query which will pull the data from the source table and then the result set returned from the sub-query will be used to provide the VALUES used for the INSERT command
Here is the basic structure, note that the VALUES keyword is not used:
INSERT INTO `table1`
(`dateavg`, `avg_temperature`)
SELECT `date` , avg(`temperature`)
FROM `test`;
Its also important to note that the position of the columns returned by result set will be sequentially matched to its respective position in the INSERT fields of the outer query
e.g. if you had a query
INSERT INTO table1 (`foo`, `bar`, `baz`)
SELECT (`a`, `y`, `g`) FROM table2
a would be inserted into foo
y would go into bar
g would go into baz
due to their respective positions
I have made a working demo - http://www.sqlfiddle.com/#!9/ff740/4
I made the below changes to simplify the example and just demonstrate the concept involved.
Here is the DDL changes I made to your original code
CREATE TABLE `test` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`date` DATETIME NOT NULL,
`temperature` FLOAT NOT NULL,
`wind_speed` INT(10),
`humidity` FLOAT ,
PRIMARY KEY (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin;
CREATE TABLE `table1` (
`idsea_state` INT(10) NOT NULL AUTO_INCREMENT,
`dateavg` VARCHAR(55),
`avg_temperature` VARCHAR(25),
PRIMARY KEY (`idsea_state`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin;
INSERT INTO `test`
(`date`, `temperature`) VALUES
('2013-05-03', 7.5),
('2013-06-12', 17.5),
('2013-10-12', 37.5);
INSERT INTO `table1`
(`dateavg`, `avg_temperature`)
SELECT `date` , avg(`temperature`)
FROM `test`;

Related

Create Table with default nextVal from sequence in Snowflake

I am currently trying to convert a postgres query to be compatible with Snowflake and work the same way.
Postgres
CREATE SEQUENCE IF NOT EXISTS public.etl_jobs_delta_loading_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE TABLE IF NOT EXISTS public.etl_jobs_delta_loading
(
id INTEGER DEFAULT nextval('public.etl_jobs_delta_loading_id_seq'::regclass) NOT NULL,
job_name VARCHAR(500) NOT NULL,
loaded_until TIMESTAMP,
etl_execution_time TIMESTAMP,
execution_status VARCHAR(30)
);
I translated the sequence to Snowflake, but keep getting errors while trying to get the nextVal in snowflake.
Snowflake
CREATE OR REPLACE SEQUENCE etl_jobs_delta_loading_id_seq
START = 1
INCREMENT = 1
CREATE TABLE IF NOT EXISTS public.etl_jobs_delta_loading
(
id INTEGER DEFAULT nextval('public.etl_jobs_delta_loading_id_seq'::regclass) NOT NULL, -- statement that needs to be converted
job_name VARCHAR(500) NOT NULL,
loaded_until TIMESTAMP,
etl_execution_time TIMESTAMP,
execution_status VARCHAR(30)
);
I have tried various approaches on creating the etl_jobs_delta_loading table but no luck till now. Any ideas on how to implement this in snowflake?
The correct syntax to get value from sequence is <seq_name>.NEXTVAL:
CREATE OR REPLACE SEQUENCE PUBLIC.etl_jobs_delta_loading_id_seq
START = 1
INCREMENT = 1;
CREATE TABLE IF NOT EXISTS public.etl_jobs_delta_loading
(
id INTEGER DEFAULT public.etl_jobs_delta_loading_id_seq.NEXTVAL NOT NULL,
job_name VARCHAR(500) NOT NULL,
loaded_until TIMESTAMP,
etl_execution_time TIMESTAMP,
execution_status VARCHAR(30)
);
Related: Sequences as Expressions
Alternatively using IDENTITY/AUTOINCREMENT property:
CREATE OR REPLACE TABLE public.etl_jobs_delta_loading
(
id INTEGER NOT NULL IDENTITY(1,1),
job_name VARCHAR(500) NOT NULL,
loaded_until TIMESTAMP,
etl_execution_time TIMESTAMP,
execution_status VARCHAR(30)
);

PostgreSQL: some troubles to insert from select with on conflict

I have some Postgres tables:
CREATE TABLE source_redshift.staticprompts (
id INT,
projectid BIGINT,
scriptid INT,
promptnum INT,
prompttype VARCHAR(20),
inputs VARCHAR(2000),
attributes VARCHAR(2000),
text VARCHAR(2000),
corpuscode VARCHAR(2000),
comment VARCHAR(2000),
created TIMESTAMP,
modified TIMESTAMP
);
and
CREATE TABLE target_redshift.user_input_conf (
collect_project_id BIGINT NOT NULL UNIQUE,
prompt_type VARCHAR(20),
prompt_input_desc VARCHAR(300),
prompt_input_name VARCHAR(100),
no_of_prompt_count BIGINT,
prompt_input_value VARCHAR(100) UNIQUE,
prompt_input_value_id BIGSERIAL PRIMARY KEY,
script_id BIGINT,
corpuscode VARCHAR(20),
min_recordings VARCHAR(2000),
max_recordings VARCHAR(2000),
recordings_count VARCHAR(2000),
lease_duration VARCHAR(2000),
date_created TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
date_updated TIMESTAMP WITHOUT TIME ZONE,
CONSTRAINT must_be_different UNIQUE (prompt_input_value,collect_project_id)
);
I need copy data from staticprompts to user_input_conf with this rules:
Primary Key : prompt_input_value_id
Unique Values : collect_project_id, prompt_input_value
Data Load Logic :
Insert only when new prompt input value is found for given collect project from source. Inputs column stores the values in JSON format in staticprompts table.
Insert :
Generate unique sequence number for each of the new prompt input value for a collect project id from source and store in prompt_input_value_id.
Update :
If prompt value already exists for a collect project and if there are any value changes on prompt_input_desc or prompt input name or prompt input value then update only those columns.
prompt_input_value_id - Generate unique sequence number for the combination of each prompt_input_value and collect_project_id
prompt_input_value - Inputs.value is stored in the inputs column as JSON text. Create a unique record for each inputs.value. Look at the example below this table.
I try to use this query:
INSERT INTO target_redshift.user_input_conf AS t (
collect_project_id,
prompt_type,
prompt_input_desc,
prompt_input_name,
prompt_input_value,
script_id,
corpuscode)
SELECT
s.projectid,
s.prompttype,
s.inputs::jsonb#>>'{inputs,0,desc}' AS desc,
s.inputs::jsonb#>>'{inputs,0,name}' AS name,
s.inputs::jsonb#>>'{inputs,0,values}' AS values,
s.scriptid,
s.corpuscode
FROM source_redshift.staticprompts AS s
ON CONFLICT (collect_project_id, prompt_input_value)
DO UPDATE SET
(prompt_input_desc, prompt_input_name, prompt_input_value, date_updated) =
(EXCLUDED.prompt_input_desc, EXCLUDED.prompt_input_name, EXCLUDED.prompt_input_value, NOW())
WHERE t.prompt_input_desc != EXCLUDED.prompt_input_desc
OR t.prompt_input_name != EXCLUDED.prompt_input_name
OR t.prompt_input_value != EXCLUDED.prompt_input_value;
""")
But I get an error:
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "user_input_conf_collect_project_id_key"
DETAIL: Key (collect_project_id)=(1) already exists.
I think there is a misunderstanding. A unique constraint over two columns does not mean that each of the columns is unique, but that the combination of the two columns is unique.
So your must_be_different is different (and weaker) than the unique constraints on prompt_input_value and collect_project_id. For example, if you have the three rows
collect_project_id | prompt_input_value
--------------------+--------------------
1 | a
1 | b
2 | b
they will create a conflict with both single-column unique constraints, but nor with must_be_different.
I guess that the underlying problem is that you want to use INSERT ... ON CONFLICT with multiple unique constraints. That cannot be done; see this question for a discussion and potential solutions.

A view that shows the name of the server, the id of the instance and the number of active sessions (a session is active if the end timestamp is null)

CREATE TABLE instances(
ser_name VARCHAR(20) NOT NULL,
id INTEGER NOT NULL ,
ser_ip VARCHAR(16) NOT NULL,
status VARCHAR(10) NOT NULL,
creation_ts TIMESTAMP,
CONSTRAINT instance_id PRIMARY KEY(id)
);
CREATE TABLE characters(
nickname VARCHAR(15) NOT NULL,
type VARCHAR(10) NOT NULL,
c_level INTEGER NOT NULL,
game_data VARCHAR(40) NOT NULL,
start_ts TIMESTAMP ,
end_ts TIMESTAMP NULL ,
player_ip VARCHAR(16) NOT NULL,
instance_id INTEGER NOT NULL,
player_username VARCHAR(15),
CONSTRAINT chara_nick PRIMARY KEY(nickname)
);
ALTER TABLE
instances ADD CONSTRAINT ins_ser_name FOREIGN KEY(ser_name) REFERENCES servers(name);
ALTER TABLE
instances ADD CONSTRAINT ins_ser_ip FOREIGN KEY(ser_ip) REFERENCES servers(ip);
ALTER TABLE
characters ADD CONSTRAINT chara_inst_id FOREIGN KEY(instance_id) REFERENCES instances(id);
ALTER TABLE
characters ADD CONSTRAINT chara_player_username FOREIGN KEY(player_username) REFERENCES players(username);
insert into instances values
('serverA','1','138.201.233.18','active','2020-10-20'),
('serverB','2','138.201.233.19','active','2020-10-20'),
('serverE','3','138.201.233.14','active','2020-10-20');
insert into characters values
('characterA','typeA','1','Game data of characterA','2020-07-18 02:12:12','2020-07-18 02:32:30','192.188.11.1','1','nabin123'),
('characterB','typeB','3','Game data of characterB','2020-07-19 02:10:12',null,'192.180.12.1','2','rabin123'),
('characterC','typeC','1','Game data of characterC','2020-07-18 02:12:12',null,'192.189.10.1','3','sabin123'),
('characterD','typeA','1','Game data of characterD','2020-07-18 02:12:12','2020-07-18 02:32:30','192.178.11.1','2','nabin123'),
('characterE','typeB','3','Game data of characterE','2020-07-19 02:10:12',null,'192.190.12.1','1','rabin123'),
('characterF','typeC','1','Game data of characterF','2020-07-18 02:12:12',null,'192.188.10.1','3','sabin123'),
('characterG','typeD','1','Game data of characterG','2020-07-18 02:12:12',null,'192.188.13.1','1','nabin123'),
('characterH','typeD','3','Game data of characterH','2020-07-19 02:10:12',null,'192.180.17.1','2','bipin123'),
('characterI','typeD','1','Game data of characterI','2020-07-18 02:12:12','2020-07-18 02:32:30','192.189.18.1','3','dhiraj123'),
('characterJ','typeD','3','Game data of characterJ','2020-07-18 02:12:12',null,'192.178.19.1','2','prabin123'),
('characterK','typeB','4','Game data of characterK','2020-07-19 02:10:12','2020-07-19 02:11:30','192.190.20.1','1','rabin123'),
('characterL','typeC','2','Game data of characterL','2020-07-18 02:12:12',null,'192.192.11.1','3','sabin123'),
('characterM','typeC','3','Game data of characterM','2020-07-18 02:12:12',null,'192.192.11.1','2','sabin123');
here I need a view that shows the name of the server, the id of the instance and the number of active sessions (a session is active if the end timestamp is null). do my code wrong or something else? i am starting to learn so hoping for positive best answers.
my view
create view active_sessions as
select i.ser_name, i.id, count(end_ts) as active
from instances i, characters c
where i.id=c.instance_id and c.end_ts = null
group by i.ser_name, i.id;
This does not do what you want:
where i.id = c.instance_id and c.end_ts = null
Nothing is equal to null. You need is null to check a value against null.
Also, count(end_ts) will always produce 0, as we know already that end_ts is null, which count() does not consider.
Finally, I would highly recommend using a standard join (with the on keyword), rather than an implicit join (with a comma in the from clause): this old syntax from decades ago should not be used in new code. I think that a left join is closer to what you want (it would also take in account instances that have no character at all).
So:
create view active_sessions as
select i.ser_name, i.id, count(c.nickname) as active
from instances i
left join characters c on i.id = c.instance_id and c.end_ts is null
group by i.ser_name, i.id;

How to select last value insert in column ( like function LAST() for OracleDB)

I'm actually sutend and I'm setting up DB PostgreSQL for my AirsoftShop and some request on it. I need to find similar function as SELECT LAST(xx) FROM yy usable on SQL server and OracleDB i think. For return the last insert values in the column target by LAST().
I have this table :
CREATE TABLE munition.suivi_ammo (
type_ammo integer NOT NULL,
calibre integer NOT NULL,
event integer NOT NULL,
date_event date NOT NULL,
entrance integer NOT NULL,
exit integer NOT NULL,
inventory integer NOT NULL,
FOREIGN KEY (calibre) REFERENCES munition.index(numero),
FOREIGN KEY (event) REFERENCES munition.index(numero),
FOREIGN KEY (type_ammo) REFERENCES munition.index(numero)
);
and index for definition by number id :
CREATE TABLE munition.index (
numero integer NOT NULL,
definition text NOT NULL,
PRIMARY KEY (numero)
);
I want to select the last inventory insert in the table and calculate the current inventory according to the inflow and outflow made after my inventory
It's works when i do this type of request with specific date to be sure to only have the last one inventory, but I do not want to have to do it
SELECT index.definition,
Sum(suivi_ammo.inventory) + Sum(suivi_ammo.entrance) - Sum(suivi_ammo.exit) AS Stock
FROM munition.suivi_ammo
INNER JOIN munition.index ON suivi_ammo.type_ammo = index.numero
WHERE date_event < '03/05/2019' AND date_event >= '2019-04-10'
GROUP BY index.definition;
I also tried to used last_value() window function but doesn't work.
Thx !

How to insert to Postgresql geometry column

I have a WKT data which looks like so:
GEOMETRYCOLLECTION(
POINT(-1763555.1165955865 310640.0829509564),
POINT(-1421117.229877997 -300856.1433304538)
)
The default projection is 'EPSG:3857'. In postgresql I created a parent table whith generic geometry column and several child tables with columns of specific geometry type. The schema looks like so:
# parent table with generic geometry column "geom"
CREATE TABLE "public"."layer_261_" (
"id" int4 DEFAULT nextval('layer_261__id_seq'::regclass) NOT NULL,
"feature_id" int4 DEFAULT 0 NOT NULL,
"feature_name" varchar(200),
"feature_type" varchar(50),
"geom" "public"."geometry",
"object_id" int4 DEFAULT 0 NOT NULL,
"row_id" int4 DEFAULT 0 NOT NULL
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."layer_261_" ADD CHECK (st_srid(geom) = 3857);
ALTER TABLE "public"."layer_261_" ADD CHECK (st_ndims(geom) = 2);
ALTER TABLE "public"."layer_261_" ADD PRIMARY KEY ("id");
# child table which is supposed to contain only POINT data type
CREATE TABLE "public"."layer_261_points" (
"id" int4 DEFAULT nextval('layer_261__id_seq'::regclass) NOT NULL,
"feature_id" int4 DEFAULT 0 NOT NULL,
"feature_name" varchar(200),
"feature_type" varchar(50),
"geom" "public"."geometry",
"object_id" int4 DEFAULT 0 NOT NULL,
"row_id" int4 DEFAULT 0 NOT NULL
)
INHERITS ("public"."layer_261_")
WITH (OIDS=FALSE);
ALTER TABLE "public"."layer_261_points" ADD CHECK (st_ndims(geom) = 2);
ALTER TABLE "public"."layer_261_points" ADD CHECK (geometrytype(geom) = 'POINT'::text);
ALTER TABLE "public"."layer_261_points" ADD CHECK (st_srid(geom) = 3857);
So, how can I insert my data (two points to the database)? For example, I'm not sure whether I should convert points' coordinates to lat-lon. And besides, I'm not sure whether I should insert GEOMETRYCOLLECTION or all points one by one.
EDIT
I've just tried to execute a query with a real data point:
INSERT INTO layer_261_ (geom) VALUES (ST_Point(105177.3509204, -85609.471679397))
But as a result I got this error message:
new row for relation "layer_261_" violates check constraint
"enforce_srid_geom"
Does anybody know how to fix it?
EDIT
This query leads to the very same error message:
INSERT INTO layer_261_ (geom) VALUES (ST_SetSRID(ST_Point(105177.3509204, -85609.471679397),
4326))
You can only insert the WKT into the parent table because the point table won't accept a GEOMETRYCOLLECTION:
INSERT INTO "public"."layer_261_" ("geom", <other columns>)
VALUES (ST_GeomFromText(<your WKT>, 3857), <other values>);
Once you have the data in the parent table you can easily convert from the GEOMETRYCOLLECTION to separate POINTs using ST_Dump() and insert those in the point table:
INSERT INTO "public"."layer_261_points" ("geom", <other columns>)
SELECT p.geom, <other columns>
FROM "public"."layer_261_" m, ST_Dump("geom") p
WHERE ...;
You can of course also forget about the first step and do ST_Dump(ST_GeomFromText(<your WKT>, 3857)) in the second step but that is less intuitive and more prone to errors.
Note that ST_Dump() is a table function so it should be used in a FROM clause. It can then use columns from tables specified before the function.
The error you were getting from using ST_Point() is because you the geometry has a NULL SRID. You should set that explicitly with ST_SetSRID() (one of my great annoyances with PostGIS...).