Creating SQL table with array value - sql

What is the best way to create table in SQL database for my situation? Option 1 or Option 2?
TMyRecord = record
id : integer;
name : string;
price : Array [0.100] of double;
If i want to create table in SQL database,
Option 1: - Creating one table and use ID and Name for all price entries.
CREATE TABLE My_Record
(
ID int,
Name varchar(255),
price float,
);
or Option 2: - use two tables and link each other?
CREATE TABLE My_Record
(
ID int,
Name varchar(255),
price float,
PRIMARY KEY (P_Id)
);
CREATE TABLE My_Record_ArrayData
(
FOREIGN KEY (ID) REFERENCES My_Record(ID)
price float,
);
Thanks in advance.

Option 2 is better, as you don't repeat Name column for each price value.
Also you just need to store ID,Name in My_Record in the second option , all price values can go to My_Record_ArrayData
another option is to go with XML data type to store all price values then you will have only one table with all values for that Name.

Related

Populate snowflake table with default values without selecting default column values from the file data

I am trying to load a table (drop table and load the data - similar to truncate and load) dynamically. Let us assume that table needs to have 4 fields, ID, Name, SeqNo, and DtTimeStamp.
The data is being selected from an externally staged csv\text file that has only two fields (ID and Name). The below query gives an error for the nonmatching of a number of columns. How to resolve that issue?
CREATE OR REPLACE TABLE SOMETABLENAME(ID NUMBER(38,0), Name
VARCHAR(255), SeqNo NUMBER(38,0) NOT NULL AUTOINCREMENT, DtTimeStamp
TIMESTAMP_NTZ(9) NOT NULL DEFAULT CURRENT_TIMESTAMP()) AS SELECT A.$1
AS ID, A.$2 AS Name FROM #EXTERNALSTAGE/SOME_FILE.CSV A;
If you carefully look at the above SQL statement, my table has two extra fields that need to be auto-populated for every row it loads. But I am unable to make it work?
Any suggestions are highly appreciated.
Thanks in Advance!
Sathya
CREATE TABLE … AS SELECT (CTAS)
CREATE TABLE <table_name> ( <col1_name> , <col2_name> , ... ) AS SELECT ...
The number of column names specified must match the number of SELECT list items in the query; the types of the columns are inferred from the types produced by the query.
To resolve it, CTAS and INSERT INTO could be two separate steps:
CREATE OR REPLACE TABLE SOMETABLENAME(
ID NUMBER(38,0),
Name VARCHAR(255),
SeqNo NUMBER(38,0) NOT NULL AUTOINCREMENT,
DtTimeStamp TIMESTAMP_NTZ(9) NOT NULL DEFAULT CURRENT_TIMESTAMP()
);
-- here INSERT/SELECT have matching column list
INSERT INTO SOMETABLENAME(ID, Name)
SELECT A.$1 AS ID, A.$2 AS Name FROM #EXTERNALSTAGE/SOME_FILE.CSV A;

How to select from table A and then insert selected id inside table B with one query?

I'm trying to implement a very basic banking system.
the goal is to have different types of transactions ( deposit, withdraw, transfer ) inside a table and refer to them as IDs inside transaction tables.
CREATE TABLE transaction_types (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
name VARCHAR UNIQUE NOT NULL
)
CREATE TABLE transactions (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
type_id INTEGER NOT NULL,
amount FLOAT NOT NULL
)
What I'm trying to accomplish is:
When inserting into transactions table no record can have an invalid type_id ( type_id should exist in transaction_types table )
First of all get type_id from transaction_types table and then insert inside transactions table, with one query ( if it's possible, I'm fairly new )
I'm using Node.js/Typescript and PostgreSQL, any help is appreciated a lot.
For (1): modify Transactions table definition by adding REFERENCES transaction_types(id) to the end of the type_id column definition prior to the comma.
For (2), assuming you know the name of the transaction_type, you can accomplish this by:
INSERT INTO transactions(type_id, amount)
VALUES ((SELECT id from transaction_types WHERE name = 'Withdrawal'), 999.99)
By the way, my PostgreSQL requires SERIAL instead of INTEGER AUTOINCREMENT

Postgresql SET DEFAULT value from another table SQL

I'm making a sql script so I have create tables, now I have a new table that have columns. One column has a FOREIGN KEY so I need this value to be SET DEFAULT at the value of the value of the original table. For example consider this two table
PERSON(Name,Surename,ID,Age);
EMPLOYER(Name,Surname,Sector,Age);
In Employer I need AGE to be setted on default on the AGE of Person, this only if PERSON have rows or just 1 row.
ID is Primary key for person and Surname,Sector for employer and AGE is FOREIGN KEY in Employer refferenced from Person
Example sql :
CREATE TABLE PERSON(
name VARCHAR(30) ,
surename VARCHAR(20),
ID VARCHAR(50) PRIMARY KEY,
Age INT NOT NULL,
);
CREATE TABLE EMPLOYER(
name VARCHAR(30) ,
Surename VARCHAR(20),
Sector VARCHAR(20),
Age INT NOT NULL,
PRIMARY KEY (Surename,Sector),
FOREIGN KEY (Age) REFERENCES Person(Age) //HERE SET DEFAULT Person(Age), how'??
);
Taking away the poor design choices of this exercise it is possible to assign the value of a column to that of another one using a trigger.
Rough working example below:
create table a (
cola int,
colb int) ;
create table b (
colc int,
cold int);
Create or replace function fn()
returns trigger
as $$ begin
if new.cold is null then
new.cold = (select colb from a where cola = new.colc);
end if;
return new;
end;
$$ language plpgsql;
CREATE TRIGGER
fn
BEFORE INSERT ON
b
FOR EACH ROW EXECUTE PROCEDURE
fn();
Use a trigger rather than a default. I have done things like this (useful occasionally for aggregated full text vectors among other things).
You cannot use a default here because you have no access to the current row data. Therefore there is nothing to look up if it is depending on your values currently being saved.
Instead you want to create a BEFORE trigger which sets the value if it is not set, and looks up data. Note that this has a different limitation because DEFAULT looks at the query (was a value specified) while a trigger looks at the value (i.e. what does your current row look like). Consequently a default can be avoided by explicitly passing in a NULL. But a trigger will populate that anyway.

SQL: Creating table with Enum-like attribute that is one of only several types

Does SQL have an OR or | equivalent for attribute types that are only one of a few possibliities (ie Enum types)?
Example using my best guess for the status attribute in the following table:
CREATE TABLE Rental (
status ("open" | "closed"),
date datetime,
id int PRIMARY KEY
)
I want status to be either "open" or "closed", nothing else. Is there syntax for this, or should I use CHAR(6) or should I use a constraint instead?
You may use check constraints when defining you table to narrow the domain of the attribute.
CREATE TABLE Rental (
status char(6),
date datetime,
id int PRIMARY KEY
);
alter table Rental
add constraint status_valid_value
check (status is null or (status in ('open','closed')));
CREATE TABLE Rental (
status char(6),
date datetime,
id int PRIMARY KEY
Check (status='open' OR status='closed')
)
It's also better to store status like int (1- open, 0 - closed, an so on)

Create a table of two types in PostgreSQL

I have created two types:
Create Type info_typ_1 AS (
Prod_id integer,
category integer);
Create Type movie_typ AS(
title varchar(50),
actor varchar(50),
price float);
And I want to create a table that consists of these two types. I know that for a table that consists of one type, it's:
CREATE TABLE Table1 of type1
(
primary key(prod_id)
);
Is there any way to do that for the two types I created above?
What I tried doing(which is wrong), is creating a third type that contains the first two:
Create Type info_ AS (
info info_typ_1,
movie movie_typ);
and then creating the table:
CREATE TABLE table1 of info_
(
primary key(Prod_id)
);
But it doesn't work. I get this error:
ERROR: column "prod_id" named in key does not exist
LINE 3: primary key(Prod_id)
^
********** Error **********
ERROR: column "prod_id" named in key does not exist
SQL state: 42703
Character: 43
You cannot make prod_id the primary key of table1 because the only columns are the two composite types info and movie. You cannot access the base types of these composite types in a PRIMARY KEY clause.
What you were trying to do works with a pk constraint on info or movie.
Except, it's probably not what you were looking for, which is not possible this way.
You could implement something like this with ...
Inheritance
Here you can inherit from multiple parent tables (substitute for your types). Example:
CREATE TABLE info (
prod_id integer
,category integer
);
CREATE TABLE movie (
title text
,actor text
,price float
);
CREATE TABLE movie_info (
PRIMARY KEY(prod_id) -- now we can use the base column!
)
INHERITS (info, movie);
INSERT INTO movie_info (prod_id, category, title, actor, price)
VALUES (1, 2, 'who donnit?', 'James Dean', '15.90');
SELECT * FROM movie_info;
-> SQLfiddle demonstrating both.
Be sure to read about limitations of inheritance in the manual.