Insert automatically large amount of records in postgresSQL table - postgresql

i need to populate my table randomly with large amount of record in PostgresSQL like 200k
CREATE TABLE qr_code.tbl_transaction (
transaction_id varchar NOT NULL,
importo numeric NOT NULL,
alias varchar NOT NULL,
order_id varchar NOT NULL,
filiale varchar NOT NULL,
descrizione varchar NOT NULL,
data_creazione timestamp NOT NULL,
terminale varchar NOT NULL,
data_esecuzione timestamp NULL,
chiave_movimento_prenotata varchar NULL,
stato varchar NULL,
codice_fiscale varchar(16) NULL,
CONSTRAINT tbl_transaction_pk PRIMARY KEY (transaction_id)
);
How can i do this quickly?

You can use generate_series() to generate a lot of rows and use random() to generate random values.
Something like:
insert into tbl_transaction (transaction_id, importo, alias, order_id, filiale, descrizione, data_creazione, terminale, data_esecuzione, chiave_movimento_prenotata, stato, codice_fiscale)
select g.id::text,
random() * 1000,
'some alias',
(random()*10000 + 1)::text,
md5(random()::text),
md5(random()::text),
timestamp '2000-01-01' + make_interval(days => (random() * 7500 + 1)::int),
md5(random()::text),
timestamp '2000-01-01' + make_interval(days => (random() * 7500 + 1)::int),
md5(random()::text),
case (id % 5) + 1
when 1 then 'one'
when 2 then 'two'
when 3 then 'three'
when 4 then 'four'
when 5 then 'five'
else 'unknonw'
end,
'some_codice'
from generate_series(1,200000) as g(id);

Related

Ordering contents of T-SQL STRING_AGG() [duplicate]

I have this query (I am using SQL Server 2019) and is working fine (combining Dates and Notes into one column). However, the result I am looking for is to have the latest date show up first.
How can I achieve that from this query?
SELECT ID,
​(SELECT string_agg(​concat(Date, ': ', Notes), CHAR(13) + CHAR(10) + CHAR(13) + CHAR (10)) as Expr1​
FROM(SELECT DISTINCT nd.Notes, nd.Date
FROM dbo.ReleaseTrackerNotes AS nd
INNER JOIN dbo.ReleaseTracker AS ac4 ON ac4.ID = nd.ReleaseTrackerID
WHERE (ac4.ID = ac.ID)) AS z_1) AS vNotes
FROM dbo.ReleaseTracker AS ac
GROUP BY ID
I have tried the ORDER BY but is not working
Here is my table:
CREATE TABLE [dbo].[ReleaseTrackerNotes](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ReleaseTrackerID] [int] NULL,
[AOC_ModelID] [int] NULL,
[Date] [date] NULL,
[Notes] [nvarchar](800) NULL,
CONSTRAINT [PK_ReleaseTrackerNotes] PRIMARY KEY CLUSTERED
CREATE TABLE [dbo].[ReleaseTracker](
[ID] [int] IDENTITY(1,1) NOT NULL,
[AOC_ModelID] [int] NOT NULL,
[MotherboardID] [int] NOT NULL,
[StatusID] [int] NOT NULL,
[TestCateoryID] [int] NULL,
[TestTypeID] [int] NULL,
[DateStarted] [date] NULL,
[DateCompleted] [date] NULL,
[LCS#/ORS#] [nvarchar](20) NULL,
[ETCDate] [date] NULL,
[CardsNeeded] [nvarchar](2) NULL,
CONSTRAINT [PK_Compatibility] PRIMARY KEY CLUSTERED
Use WITHIN GROUP (ORDER BY ...):
SELECT
ID,
STRING_AGG(​TRY_CONVERT(varchar, Date, 101) + ': ' + Notes +
CHAR(13) + CHAR(10) + CHAR(13), CHAR(10))
WITHIN GROUP (ORDER BY Date DESC) AS Expr1​
FROM
(
SELECT DISTINCT ac4.ID, nd.Notes, nd.Date
FROM dbo.ReleaseTrackerNotes AS nd
INNER JOIN dbo.ReleaseTracker AS ac4
ON ac4.ID = nd.ReleaseTrackerID
) AS vNotes
GROUP BY ID;

I think I am missing something

I need to create an insert statement and it is not working? would love some help. I get no relation. Here is my code:
INSERT INTO movies table (movie_id, release_year, movie_title,movie_descrption, number_in_stock_,rental_or_sale_or_both, rental_daily_rate)
INSERT INTO movies VALUES('10101', '1985','top gun', 'airplains', '50', 'both', '$5'
And here is my table
SQL database table for Movies tables
CREATE TABLE movies_id
(
movie_id VARCHAR NOT NULL PRIMARY KEY,
release_year DATE NOT NULL,
movie_title VARCHAR (50) NOT NULL,
movie_description VARCHAR (50) NOT NULL,
number_in_stock VARCHAR (50) NOT NULL,
rental_or_sale_or_both VARCHAR (50) NOT NULL,
rental_daily_rate VARCHAR (50) NOT NULL
);
'1985' is not a correct DATE value, some field names are mistyped. Try with following statements:
CREATE TABLE movies_id
(
movie_id VARCHAR NOT NULL PRIMARY KEY,
release_year DATE NOT NULL,
movie_title VARCHAR (50) NOT NULL,
movie_description VARCHAR (50) NOT NULL,
number_in_stock VARCHAR (50) NOT NULL,
rental_or_sale_or_both VARCHAR (50) NOT NULL,
rental_daily_rate VARCHAR (50) NOT NULL
);
INSERT INTO movies_id
(movie_id, release_year, movie_title, movie_description, number_in_stock,
rental_or_sale_or_both, rental_daily_rate)
VALUES ('10101', '1985-01-01','top gun', 'airplains', '50', 'both', '$5')
Working Demo
The correct way is:
INSERT INTO movies (movie_id, release_year, movie_title,movie_descrption, number_in_stock_,rental_or_sale_or_both, rental_daily_rate) VALUES('10101', '1985','top gun', 'airplains', '50', 'both', '$5')
or short version insert (considering the creation' order of attributes in table)
INSERT INTO movies VALUES('10101', '1985','top gun', 'airplains', '50', 'both', '$5')
Try to this first create this table and run the insert syntax
Create Table movies(movie_id VARCHAR Not NULL PRIMARY key,
release_year date not null,
movie_title VARCHAR (50) NOT NULL,
movie_description VARCHAR (50) NOT NULL,
number_in_stock VARCHAR (50) NOT NULL,
rental_or_sale_or_both VARCHAR (50) NOT NULL,
rental_daily_rate VARCHAR (50) NOT NULL
);
insert into movies values('10101', '1985','top gun', 'airplains', '50', 'both', '$5');

How to compute a derived age attribute in postgresql?

I have the following person table with the dbirth column (date of birth). I need to compute the column age. I has been trying, but I have the following ERROR: generation expression is not immutable. I would greatly appreciate any help.
CREATE TABLE person
(
person_id SERIAL NOT NULL,
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
ssn CHAR(10) NOT NULL,
pnumber CHAR(12) NOT NULL,
dbirth DATE NOT NULL,
age integer GENERATED ALWAYS AS ( extract( year FROM CURRENT_DATE ) - extract( year FROM dbirth)) STORED,
address_id INTEGER NOT NULL,
sex_id INTEGER NOT NULL,
PRIMARY KEY ( person_id ),
FOREIGN KEY ( sex_id ) REFERENCES sex ( sex_id ),
FOREIGN KEY ( address_id ) REFERENCES address ( address_id )
);
The reason is EXTRACT function is not an IMMUTABLE.
Create your own custom IMMUTABLE function and use it in the generated column.
Example: Function to get_age as an Interval contains Year, Month and days
CREATE OR REPLACE FUNCTION get_age( birthday date )
RETURNS interval
AS $CODE$
BEGIN
RETURN age(birthday);
END
$CODE$
LANGUAGE plpgsql IMMUTABLE;
Then use the IMMUTABLE function in the generated column
CREATE TABLE person
(
person_id SERIAL NOT NULL,
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
ssn CHAR(10) NOT NULL,
pnumber CHAR(12) NOT NULL,
dbirth DATE NOT NULL,
age interval GENERATED ALWAYS AS (get_age(dbirth)) STORED,
address_id INTEGER NOT NULL,
sex_id INTEGER NOT NULL,
PRIMARY KEY ( person_id ),
FOREIGN KEY ( sex_id ) REFERENCES sex ( sex_id ),
FOREIGN KEY ( address_id ) REFERENCES address ( address_id )
);
Note: Age is an Interval datatype if you want to use it as an int modify the get_age function.
You do not want a generated column for age. Postgres only supports STORED generated columns, the problem comes in that the age column is NOT update unless dbirth is updated.
-- setup
create or replace function get_age( from_date timestamptz )
returns interval
language sql immutable
as $$
select age(from_date);
$$;
create table test_person
( person_id serial
, fname varchar(10) not null
, pnumber varchar(12) not null
, dbirth timestamptz(6) not null
, age interval generated always as (get_age(dbirth)) stored
);
insert into test_person(fname,pnumber,dbirth)
values ('MSam', '555-937-9292', '1995-06-23 08:00:01.344612'::timestamptz )
, ('WSam', '555-937-9292', '2019-03-21 15:32:18.863452'::timestamptz );
commit ;
select p.fname, p.pnumber,dbirth, p.age, current_timestamp
from test_person p
order by fname;
|fname |pnumber |dbirth |age |current_timestamp |
|----------|------------|-------------------|----------------------------|-------------------|
|MSam |555-937-9292|1995-06-23 03:00:01|25 years 24 days 15:59:58.65|2020-07-18 17:53:14|
|WSam |555-937-9292|2019-03-21 10:32:18|1 year 3 mons 27 days 08:27:|2020-07-18 17:53:14|
Now wait some time, does not have to be long, but noticeable.
Then run the exact same query.
select p.fname, p.pnumber,dbirth, p.age, current_timestamp
from test_person p
order by fname;
|fname |pnumber |dbirth |age |current_timestamp |
|----------|------------|-------------------|----------------------------|-------------------|
|MSam |555-937-9292|1995-06-23 03:00:01|25 years 24 days 15:59:58.65|2020-07-18 17:55:29|
|WSam |555-937-9292|2019-03-21 10:32:18|1 year 3 mons 27 days 08:27:|2020-07-18 17:55:29|
Notice in the above that although the current timestamp has changes (time has passed) the age has not. Have we just discovered "the Fountain Of Youth" So try a likely update, like phone number.
update test_person
set pnumber = '555-949-0070'
where fname = 'MSam';
select p.fname, p.pnumber,dbirth, p.age, current_timestamp
from test_person p
order by fname;
|fname |pnumber |dbirth |age |current_timestamp |
|----------|------------|-------------------|----------------------------|-------------------|
|MSam |555-949-0070|1995-06-23 03:00:01|25 years 24 days 15:59:58.65|2020-07-18 17:57:16|
|WSam |555-937-9292|2019-03-21 10:32:18|1 year 3 mons 27 days 08:27:|2020-07-18 17:57:16|
Perhaps a better solution would be:
Drop the Age column from the table completely.
Create a view having and have it generate the Age.
Write your queries against the view.
alter table test_person drop column age;
create view test_person_v as
( select t.*, age( current_timestamp, dbirth) age
from test_person t
);
);
select p.fname, p.pnumber,dbirth, p.age, current_timestamp
from test_person_v p
order by fname;
|fname |pnumber |dbirth |age |current_timestamp |
|----------|------------|-------------------|----------------------------|-------------------|
|MSam |555-949-0070|1998-06-23 03:00:01|22 years 25 days 15:37:45.54|2020-07-18 18:37:46|
|WSam |555-937-9292|2019-03-21 10:32:18|1 year 3 mons 28 days 08:05:|2020-07-18 18:37:46|
select p.fname, p.pnumber,dbirth, p.age, current_timestamp
from test_person_v p
order by fname;
|fname |pnumber |dbirth |age |current_timestamp |
|----------|------------|-------------------|----------------------------|-------------------|
|MSam |555-949-0070|1998-06-23 03:00:01|22 years 25 days 15:42:50.78|2020-07-18 18:42:52|
|WSam |555-937-9292|2019-03-21 10:32:18|1 year 3 mons 28 days 08:10:|2020-07-18 18:42:52|

How to insert characters such as "±, ≧, ≦" inside a table in PL/SQL

Here is the SQL I'm using to create my table:
create table LAB_REQUESTS_REQUREMENTS
(
id INTEGER not null,
request_id INTEGER not null,
test_id INTEGER not null,
requrement VARCHAR2(30) not null,
assistant_id INTEGER,
measured_result VARCHAR2(50),
measured_condition VARCHAR2(50),
price_id INTEGER not null,
single_price NUMBER(15,2) default 0 not null,
measured_date DATE,
measure NVARCHAR2(30),
metric_tolerance NVARCHAR2(30)
)
tablespace VIK
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
);
How should I go about inserting those characters inside 'MEASURE' for example without going through conversion when inserting and then reading from the table?

Efficiently select the most specific result from a table

I have a table roughly as follows:
CREATE TABLE t_table (
f_userid BIGINT NOT NULL
,f_groupaid BIGINT
,f_groupbid BIGINT
,f_groupcid BIGINT
,f_itemid BIGINT
,f_value TEXT
);
The groups are orthogonal, so no hierarchy can be implied beyond the fact that every entry in the table will have a user ID. There is no uniqueness in any of the columns.
So for example a simple setup might be:
INSERT INTO t_table VALUES (1, NULL, NULL, NULL, NULL, 'Value for anything by user 1');
INSERT INTO t_table VALUES (1, 5, 2, NULL, NULL, 'Value for anything by user 1 in groupA 5 groupB 2');
INSERT INTO t_table VALUES (1, 4, NULL, 1, NULL, 'Value for anything by user 1 in groupA 5 and groupC 1');
INSERT INTO t_table VALUES (2, NULL, NULL, NULL, NULL, 'Value for anything by user 2');
INSERT INTO t_table VALUES (2, 1, NULL, NULL, NULL, 'Value for anything by user 2 in groupA 1');
INSERT INTO t_table VALUES (2, 1, 3, 4, 5, 'Value for item 5 by user 2 in groupA 1 and groupB 3 and groupC 4');
For any given set of user/groupA/groupB/groupC/item I want to be able to obtain the most specific item in the table that applies. If any of the given set are NULL then it can only match relevant columns in the table which contain NULL. For example:
// Exact match
SELECT MostSpecific(1, NULL, NULL, NULL, NULL) => "Value for anything by user 1"
// Match the second entry because groupC and item were not specified in the table and the other items matched
SELECT MostSpecific(1, 5, 2, 3, NULL) => "Value for anything by user 1 in groupA 5 groupB 2"
// Does not match the second entry because groupA is NULL in the query and set in the table
SELECT MostSpecific(1, NULL, 2, 3, 4) => "Value for anything by user 1"
The obvious approach here is for the stored procedure to work through the parameters and find out which are NULL and not, and then call the appropriate SELECT statement. But this seems very inefficient. IS there a better way of doing this?
This should do it, just filter out any non matching rows using a WHERE, then rank the remaining rows by how well they match. If any column doesn't match, the whole bop expression will result in NULL, so we filter that out in an outer query where we also order by match and limit the result to only the single best match.
CREATE FUNCTION MostSpecific(BIGINT, BIGINT, BIGINT, BIGINT, BIGINT)
RETURNS TABLE(f_userid BIGINT, f_groupaid BIGINT, f_groupbid BIGINT, f_groupcid BIGINT, f_itemid BIGINT, f_value TEXT) AS
'WITH cte AS (
SELECT *,
CASE WHEN f_groupaid IS NULL THEN 0 WHEN f_groupaid = $2 THEN 1 END +
CASE WHEN f_groupbid IS NULL THEN 0 WHEN f_groupbid = $3 THEN 1 END +
CASE WHEN f_groupcid IS NULL THEN 0 WHEN f_groupcid = $4 THEN 1 END +
CASE WHEN f_itemid IS NULL THEN 0 WHEN f_itemid = $5 THEN 1 END bop
FROM t_table
WHERE f_userid = $1
AND (f_groupaid IS NULL OR f_groupaid = $2)
AND (f_groupbid IS NULL OR f_groupbid = $3)
AND (f_groupcid IS NULL OR f_groupcid = $4)
AND (f_itemid IS NULL OR f_itemid = $5)
)
SELECT f_userid, f_groupaid, f_groupbid, f_groupcid, f_itemid, f_value FROM cte
WHERE bop IS NOT NULL
ORDER BY bop DESC
LIMIT 1'
LANGUAGE SQL
//
An SQLfiddle to test with.
Try something like:
select *
from t_table t
where f_userid = $p_userid
and (t.f_groupaid is not distinct from $p_groupaid or t.f_groupaid is null) --null in f_groupaid matches both null and not null values
and (t.f_groupbid is not distinct from $p_groupbid or t.f_groupbid is null)
and (t.f_groupcid is not distinct from $p_groupcid or t.f_groupcid is null)
order by (t.f_groupaid is not distinct from $p_groupaid)::int -- order by count of matches
+(t.f_groupbid is not distinct from $p_groupbid)::int
+(t.f_groupcid is not distinct from $p_groupcid)::int desc
limit 1;
It will give you the best match on groups.
A is not distinct from B fill return true if A and B are equal or both null.
::int means cast ( as int). Casting boolean true to int will give 1 (You can not add boolean values directly).
SQL Fiddle
create or replace function mostSpecific(
p_userid bigint,
p_groupaid bigint,
p_groupbid bigint,
p_groupcid bigint,
p_itemid bigint
) returns t_table as $body$
select *
from t_table
order by
(p_userid is not distinct from f_userid or f_userid is null)::integer
+
(p_groupaid is not distinct from f_groupaid or f_userid is null)::integer
+
(p_groupbid is not distinct from f_groupbid or f_userid is null)::integer
+
(p_groupcid is not distinct from f_groupcid or f_userid is null)::integer
+
(p_itemid is not distinct from f_itemid or f_userid is null)::integer
desc
limit 1
;
$body$ language sql;