SQL Server composite key custom Auto Increment in child field - sql

I'm using SQL Server 2012 Express. I have created the following table
CREATE TABLE [dbo].[logis_location]
( [loc_id] int identity NOT NULL
, [loc_name] varchar(50) NOT NULL )
CREATE TABLE [dbo].[rev_bill]
( [bill_id] int identity NOT NULL ,
[loc_id] int NOT NULL )
ALTER TABLE [dbo].[rev_bill]
ADD CONSTRAINT [rev_bill_PK] PRIMARY KEY CLUSTERED ( [bill_id] , [loc_id] )
ALTER TABLE [dbo].[rev_bill] WITH CHECK
ADD CONSTRAINT [logis_location_rev_bill_FK1]
FOREIGN KEY ( [loc_id] )
THe bill_id is auto incrementing ,But bill table have composite key based on location table loc_id which is foreign Key.
This resulting following output
bill_id loc_id 1 1 2 1 3 2 4 2 5 1
6 3
7 2
However expected outcome is
bill_id loc_id
1 1
2 1
1 2
2 2
3 1
1 3
3 2
I want to increment the location specific bill_id in most safest way.It means when inserting new bill ,the bill id should be incremented ,but considering the loc_id.As given above, If there is bill for the given location (eg:loc_id =4), first bill for that location should have bill_id 1,and next one should be 2. This is Client requirement.
Please provide me some guide line.

Related

how to add primary key column without truncating table in oracle

We have received a requirement where we need to add a new column to primary key where table is having records:
alter table customer add (bill_to number(9,0),
CONSTRAINT CUSTOMER_PK PRIMARY KEY (bill_to));
In this case after it adds the new column to the table by default null values will be stored if table is having records, technically we cannot make this column a primary key, either table shouldn't have the records or we have to truncate the table, but we cannot do it in production,
is there any other way to deal this? please suggest.
You can do it in 2 statements by first adding an IDENTITY column and second making it the PRIMARY KEY:
So, if you have the table:
CREATE TABLE customer ( value ) AS
SELECT 'A' FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
SELECT 'B' FROM DUAL CONNECT BY LEVEL <= 2;
Then you can:
ALTER TABLE customer ADD (
bill_to NUMBER(9,0)
GENERATED ALWAYS AS IDENTITY
);
ALTER TABLE customer ADD CONSTRAINT CUSTOMER_PK PRIMARY KEY ( bill_to );
And the table becomes:
VALUE | BILL_TO
:---- | ------:
A | 1
A | 2
A | 3
B | 4
B | 5
db<>fiddle here
You can not do it in a single statement.
You can achieve it using the three-step process as follows:
ALTER TABLE CUSTOMER ADD BILL_TO NUMBER(9, 0);
UPDATE CUSTOMER
SET BILL_TO = SEQ OR ANYOTHER LOGIC FOR UNIQUE VALUE FOR EACH ROW;
ALTER TABLE CUSTOMER ADD CONSTRAINT CUSTOMER_PK PRIMARY KEY ( BILL_TO );

How to update unique table row numbers before inserting new row at existing position

SQL table:
id | name
----+--------
1 | apple
2 | orange
3 | apricot
The id is primary key, unique, could be SERIES. The goal is to insert new row where id equals 2 and shift existing row numbers below, that is 2 and 3, to 3 and 4 position.
I have tried shift rows before inserting new row:
"UPDATE some_table SET id = id + 1 WHERE id >= id"
but an error occurred:
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "some_table_pkey"
Detail: Key (id)=(3) already exists.
Is there some effective way to do such an operation?
The table should look like this after update:
id | name
----+--------
1 | apple
2 | cherry
3 | orange
4 | apricot
While I think the attempt is futile, you can achieve that by marking the primary key constraint as deferrable:
CREATE TABLE some_table
(
id int,
name text
);
alter table some_table
add constraint pk_some_table
primary key (id)
deferrable initially immediate; --<< HERE
In that case the PK constraint is evaluated at per statement, not per row.
Online example: https://rextester.com/JSIV60771
update Names
set id=id+1
where id in
(select id from Names where id>=2 order by id desc);
Here first you can update the id's and then you can insert
insert into Names (id,name) values(2,'cheery')

Auto Increment Composite Primary Key

I have an Access database that I am trying to create. I want to use two columns from the table to create the primary key.
Projectbl (ProjectID, ProjectRegion, other columns)
I want the ProjectID to autoincrement. That's fine. So far whenever I add a new project, the ProjecID increments by itself.
I want to create a new column in that same table that will be the ProjectRef where the new number would be a composite of ProjectID and ProjectRegion.
So for example
ProjectID ProjectRegion OtherCol
---------------------------------
1 500 ...
2 100 ...
3 200 ...
4 500 ...
5 500 ...
6 100 ...
I want the table to actually look like that
ProjectRef ProjectID ProjectRegion OtherCol
--------------------------------------------
5001 1 500 ...
1002 2 100 ...
2003 3 200 ...
5004 4 500 ...
5005 5 500 ...
1006 6 100 ...
So I am trying to add a new project: the projectID will autoincrement to 7, but the ProjectRef will be 'ProjectReg'7 whatever the ProjectReg is.
I know I can create a composite key with
CREATE TABLE 'Projectbl'
(
ProjectID INT(10) NOT NULL AUTO_INCREMENT,
ProjectRegion INT(10) NOT NULL,
other columns VARCHAR(100),
CONSTRAINT ProjectRef
PRIMARY KEY ('ProjectRegion', 'ProjectID')
)
How can I actually display ProjectRef in the table?
You shouldn't have the ProjectRef column at all. This violates basic rules of database normalization. If you want your front end to display the ProjectRef then just calculate it from the columns that you have.

How to Insert Primary Value (PK) to Related Table (FK)

I'm having trouble from Inserting 1 Primary Value (Increment) of TABLE to another TABLE (Foreign Key)
Table 1 has the Primary key of Student Number; if i enter values for last and first name from TABLE 1 then the student number will automatically giving it's own value because of Increment, and else if i entered from TABLE 2, I want the value of Student Number from TABLE i will increment even the value of Last and First name if TABLE 1 is NULL
Table 1
(PK)Student_# | Last_Name | First_Name
...........1...........|........a..........|..........b.......
...........2...........|........c..........|..........b.......
Table 2
(FK)Student_# | Year_Level | Section
...........NULL................|..........2nd Year......|.....C1 .........
...........NULL................|..........3rd Year......|.....D1 .........
Needed
(FK)Student_# | Year_Level | Section
..............1...................|..........2nd Year......|.....C1 .........
..............2...................|..........3rd Year......|.....D1 .........
It sounds to me that you need a primary key with an identity seed on table2 and also a foreign key to the student table:
(PK/Identity) Table2ID | (FK)Student_# | Year_Level | Section
This way you can insert the student_# when you insert the record into table 2 and also be able to give each row in table2 a unique identifier
CREATE TABLE Table2
(
Table2ID INT IDENTITY(1,1) PRIMARY KEY
,Student_# INT NOT NULL FOREIGN KEY REFERENCES Table1(Student_#)
,Year_Level NVARCHAR(255) --Use whatever data type you need
,Section NVARCHAR(255) --Use whatever data type you need
)
I have assumed you are using sql server as you have not specified in your question. You may need to change this query for a different RDBMS.

compatibility between the same table fields

I've got shop types. Some shop types doesn't compatible with other shop types (for example you can't sell car parts near food for example).
Here is my table schema:
create table TShopCompatibility
(
idshoptype1 int NOT NULL,
idshoptype2 int NOT NULL,
constraint pkSHOPCOMP primary key(idshoptype1,idshoptype2),
constraint fkSHOPCOMP1 foreign key(idshoptype1) references TShopType(idshoptype),
constraint fkSHOPCOMP2 foreign key(idshoptype2) references TShopType(idshoptype),
constraint cSHOPCOMP12 check(idshoptype1>idshoptype2)
)
I've got these values:
2 - 1
3 - 1
5 - 1
5 - 2
10 - 9
12 - 11
13 - 10
How where id - shoptypes. How can I get what shops are compatible for example with idshoptype = 2?
You would need to select the shop types where 2 is present in idshoptype1 or idshoptype2, i.e.
SELECT idshoptype1 FROM TShopCompatibility WHERE idshoptype2 = 2
UNION
SELECT idshoptype2 FROM TShopCompatibility WHERE idshoptype1 = 2
Then you can join the result of this query with shops table to get the shop information.