Return custom type x composed of custom type y in atomic table format PostgreSQL - postgresql

I have a custom type:
CREATE TYPE single_journey AS (
tram_id integer,
departure_station text,
departure_time time,
destination_station text,
arrival_time time);
and another custom type:
CREATE TYPE double_journey AS (
journey_one single_journey,
journey_two single_journey);
The second custom type exists because I have a function that can return two single_journey types together.
The problem is, the output is like this:
journey_one journey_two
single_journey single_journey
---------------------------------------- ----------------------------------------
(39,StationX,11:00:00,StationY,12:00:00) (40,StationY,12:30:00,StationZ,13:00:00
What I desire is each column of each single_journey in double_journey to be in it's own separate column. Is this possible or would I have to re-create the double_journey type with the columns I want e.g. departure_station_1, departure_time_1...arrival_station_2, arrival_time_2 etc...?

Instead of
SELECT journey_one, journey_two
USE
SELECT journey_one,
(journey_two).field1,
(journey_two).field2,
(journey_two).field3, etc

Related

Table doesn't creates with default value [SQLalchemy]

I have table
users = Table(
"users",
metadata,
Column("id", Integer, primary_key=True),
Column("username", String(32), unique=True),
Column("password", String(64)),
Column("games_all", Integer, default=0),
Column("games_won", Integer, default=0),
Column("created_at", DateTime, default=datetime.utcnow)
)
and when i do
metadata.create_all(bind=engine)
the table is created but with an empty default field.
Image
I want the table to be created with the default values that I specified.
The column default argument is the default value set on the Python side when creating a users instance. If you want the default value to be set on the database side, use server_default.

CREATE FUNCTION failed because a column name is not specified for column 1. error for the Multiple parameter of function

Wanted to create the multiple parameter of function but it gives me this error:
CREATE FUNCTION failed because a column name is not specified for
column 1.
Code below:
create function dmt.Impacted(
#nameOfColumn varchar , #nameOfParam varchar)
returns table
as
return
(select
case when '['+#nameOfColumn+']' is null or len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else
#nameOfParam end from employee) ;
As the error message clearly said, the column in the returned result need a name. Either give it an alias in the SELECT like
SELECT CASE
...
END a_column_name
...
or define it in the declaration of the return type as in
...
RETURNS TABLE
(a_column_name nvarchar(max)
...
As you can see in the second form you have to specify a data type. As your current code doesn't make much sense now I cannot figure out what is the right one there. You'd need to amend it.
Note, that len(rtrim('['+#nameOfColumn+']')) = 0 is never true as len(rtrim('['+#nameOfColumn+']')) is either NULL, when #nameOfColumn is NULL or at least 2 because of the added brackets.
If #nameOfColumn is supposed to be a column name you shouldn't use varchar (especially without a length specified for it) but sysname which is a special type for object names.
Either way you should define a length for #nameOfColumn and #nameOfParam as just varchar without any length means varchar(1), which is probably not what you want. And maybe instead of varchar you want nvarchar.
You may also want to look into quotename().
Define name of column in SELECT statement :
(select case when '['+#nameOfColumn+']' is null or
len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else #nameOfParam
end as name_column -- define column name
from employee)
Also, your function parameter has no data length, by default it will accept only 1 character #nameOfColumn varchar , #nameOfParam varchar & rest will trim.

Is it possible to set UserDefinedTableType column default value?

I have created my own TableType, is it possible to set a date column default in order to not call GetDate() within every insert?
It's quite straightforward, as in case of regular tables, but you can not assign a name to that constraint:
CREATE TYPE TestType AS TABLE
( ID INT,
CreatedDate DATETIME DEFAULT(GETDATE())
)

How to create a PostgreSQL column that is a set of enum values?

I like that I can create new enum types in PostgreSQL. But what if I want a column value that is a set of enum values. Do I need to implement that manually with an integer column type and bitwise operators, or is there a way to keep using the enums by name?
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap')
CREATE TABLE t (
id serial,
properties [set of foo?]
)
...
SELECT * FROM t;
1 loud
2 loud, cheap
3 bright
4 none
...
You can use an array:
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap');
CREATE TABLE t (
id serial,
properties foo[]
);

Postgres query error

I have a query in postgres
insert into c_d (select * from cd where ak = '22019763');
And I get the following error
ERROR: column "region" is of type integer but expression is of type character varying
HINT: You will need to rewrite or cast the expression.
An INSERT INTO table1 SELECT * FROM table2 depends entirely on order of the columns, which is part of the table definition. It will line each column of table1 up with the column of table2 with the same order value, regardless of names.
The problem you have here is whatever column from cd with the same order value as c_d of the table "region" has an incompatible type, and an implicit typecast is not available to clear the confusion.
INSERT INTO SELECT * statements are stylistically bad form unless the two tables are defined, and will forever be defined, exactly the same way. All it takes is for a single extra column to get added to cd, and you'll start getting errors about extraneous extra columns.
If it is at all possible, what I would suggest is explicitly calling out the columns within the SELECT statement. You can call a function to change type within each of the column references (or you could define a new type cast to do this implicitly -- see CREATE CAST), and you can use AS to set the column label to match that of your target column.
If you can't do this for some reason, indicate that in your question.
Check out the PostgreSQL insert documentation. The syntax is:
INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) | query }
which here would look something like:
INSERT INTO c_d (column1, column2...) select * from cd where ak = '22019763'
This is the syntax you want to use when inserting values from one table to another where the column types and order are not exactly the same.