Set partial unique index on table creation in PostgreSQL - postgresql

When defining unique indices in PostgreSQL you have two options:
Define unique index using constraint with the table via a single statement
Define index later after table is created using separate CREATE INDEX statement
However, when it comes to unique partial indices, is it possible to create one with the table using single statement or do I have to use a separate statement?
I would prefer to define all the indices with the table.

Related

PostgreSQL Unique constraint and compound index

I have a table with a unique constraint on two fields, I also use this as an index for faster performance. I want to query a third field as part of this index but I don't want the third field to be part of the unique constraint. i.e. I don't want a new composite index just for the third field as it's quite large.
Is there a way to do this in Postgres? I presently create the unique constraint and get the index created for free, can I specify the three-field composite index and tell the unique constraint to use this index, and Postgres will figure out it can use this index as a UC?
You can use the INCLUDE option:
create unique index on the_table (column_1, column_2)
include (column_3);

Can I create index on a column with functions or analytical functions in SQL Server 2016?

Can I create an Index on a column with functions or analytical functions?
I have a table ABC with columns XXX updateddatetime, YYY updatedusername. I am trying to create indices as shown below
CREATE INDEX idx_Cname1
ON ABC(UPPER(updatedusername));
CREATE INDEX idx_Cdate1
ON ABC(YEAR(updateddatetime));
I just get an error
Incorrect syntax near '('
Is it possible to create index as shown above. Also, can I create an index on columns with analytical functions like LEAD, LAG, etc.,
Thanks in advance!
Specify Computed Columns in a Table
Create computed column
ALTER TABLE [t] ADD Cname1 AS ABC(UPPER(updatedusername))
ALTER TABLE [t] ADD Cdate1 AS ABC(YEAR(updateddatetime))
add PERSISTED no difference, the index still materializes the field
after create index
CREATE INDEX idx_Cname1
ON [T] (Cname1);
CREATE INDEX idx_Cdate1
ON [T] (Cdate1);

Will postgresql generate index automatically?

is there automatic index in Postgresql or need users to create index explicitly? if there is automatic index, how can I view it? thanks.
An index on the primary key and unique constraints will be made automatically. Use CREATE INDEX to make more indexes. To view existing database structure including the indexes, use \d table.
A quick example of generating an index would be:
CREATE INDEX unique_index_name ON table (column);
You can create an index on multiple columns:
CREATE INDEX unique_index_name ON table (column1, column2, column3);
Or a partial index which will only exist when conditions are met:
CREATE INDEX unique_index_name ON table (column) WHERE column > 0;
There is a lot more you can do with them, but that is for the documentation (linked above) to tell you. Also, if you create an index on a production database, use CREATE INDEX CONCURRENTLY (it will take longer, but not lock out new writes to the table). Let me know if you have any other questions.
Update:
If you want to view indexes with pure SQL, look at the pg_catalog.pg_indexes table:
SELECT *
FROM pg_catalog.pg_indexes
WHERE schemaname='public'
AND tablename='table';

Composite key with user-supplied string column, foreign keys

Let's say I have the following table
TABLE subgroups (
group_id t_group_id NOT NULL REFERENCES groups(group_id),
subgroup_name t_subgroup_name NOT NULL,
more attributes ...
)
subgroup_name is UNIQUE to a group(group_id).
A group can have many subgroups.
The subgroup_names are user-supplied. (I would like to avoid using a subgroup_id column. subgroup_name has meaning in the model and is more than just a label, I am providing a list of predetermined names but allow a user to add his owns for flexibility).
This table has 2 levels of referencing child tables containing subgroup attributes (with many-to-one relations);
I would like to have a PRIMARY KEY on (group_id, upper(trim(subgroup_name)));
From what I know, postgres doesn't allow to use PRIMARY KEY/UNIQUE on a function.
IIRC, the relational model also requires columns to be used as stored.
CREATE UNIQUE INDEX ON subgroups (group_id, upper(trim(subgroup_name))); doesn't solve my problem
as other tables in my model will have FOREIGN KEYs pointing to those two columns.
I see two options.
Option A)
Store a cleaned up subgroup name in subgroup_name
Add an extra column called subgroup_name_raw that would contained the uncleaned string
Option B)
Create both a UNIQUE INDEX and PRIMARY KEY on my key pair. (seems like a huge waste)
Any insights?
Note: I'm using Postgres 9.2
Actually you can do a UNIQUE constraint on the output of a function. You can't do it in the table definition though. What you need to do is create a unique index after. So something like:
CREATE UNIQUE INDEX subgroups_ukey2 ON subgroups(group_id, upper(trim(subgroup_name)));
PostgreSQL has a number of absolutely amazing indexing capabilities, and the ability to create unique (and partial unique) indexes on function output is quite underrated.

How to constrain that a table gets multiple values in t-sql?

I thought of creating a trigger in t-sql that constrains having multiple values of the same column. It has three unique keys - which needs to be unique.
How to get the current row in a t-sql trigger? Is it possible?
If those values are predefined you can create an other table which contain all these unique values and then create FK constraint.
For me it looks like as standard look up table: