Trying to create a computed column in SQL Server - sql

I am trying to create a computed column in SQL Server.
This is script to create column.
CREATE TABLE [dbo].[Invoice]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[InvoiceID] AS (('INV' + FORMAT(GETUTCDATE(), 'yyyyMMdd')) + RIGHT('000000' + CONVERT([VARCHAR](20), [ID]), (7))),
[Name] [nvarchar](50) NOT NULL,
[CreatedOn] [datetime] NOT NULL
CONSTRAINT [DF_Invoice_CreatedOn] DEFAULT (getutcdate())
) ON [PRIMARY]
GO
It will return a value for InvoiceId column like this:
ID InvoiceID Name CreatedOn
--- -------------------- ------- -----------------------
1 INV201705090000001 amki 2017-05-09 13:11:06.790
2 INV201705090000002 amkit 2017-05-09 13:11:26.600
3 INV201705090000003 amkit3 2017-05-09 13:11:32.397
4 INV201705090000004 amkit6 2017-05-09 13:11:35.070
But I want to modify it more.
When server date changes, then again it start from 1.
This is my expected output.
ID InvoiceID Name CreatedOn
--- -------------------- ------- -----------------------
1 INV201705090000001 amki 2017-05-09 13:11:06.790
2 INV201705090000002 amkit 2017-05-09 13:11:26.600
3 INV201705090000003 amkit3 2017-05-09 13:11:32.397
4 INV201705100000001 amkit6 2017-05-10 13:11:35.070
5 INV201705100000002 amkit6 2017-05-10 13:11:35.070
6 INV201705110000001 amkit6 2017-05-11 13:11:35.070
As you can see from above result, It again start from 1 where date change from 20170509 to 20170510.
If it can not be done using computed column, Then is there any other way I can achieve this.
I know there are many post related to how to create computed column. But I don't how to make it again start from 1 when date changes.

I'm with TheGameiswar on this one. I think a view (or simple query) would be best
Example
Select ID
,Invoice = concat('INV',convert(varchar(8),CreatedOn,112),right('0000000'+convert(varchar(5),Row_Number() over (Partition By convert(date,CreatedOn) Order by CreatedOn,ID)),7))
,Name
,CreatedOn
From YourTable
Returns
After Update

Related

Merging tables on weak condition

I have two tables one big mastertable and one small helper table. I need to fill values from the helper table into the mastertable. A value from the helper table has a timestamp and it shall be assigned to the next bigger timestamp occurring in the mastertable
example:
master
timestamp
mode
ID
job
2022-05-30 09:15:18.907
abc
65
Null
2022-05-29 09:07:12.980
abc
64
Null
2022-05-28 09:02:00.977
abc
63
Null
2022-05-27 09:12:24.677
abc
62
Null
helper
trigger
job
2022-05-30 09:13:12.000
1910
2022-05-29 09:05:05.000
1611
result
timestamp
mode
ID
job
2022-05-30 09:15:18.907
abc
65
1910
2022-05-29 09:07:12.980
abc
64
1611
2022-05-28 09:02:00.977
abc
63
Null
2022-05-27 09:12:24.677
abc
62
Null
The entries are deleted from helper.
It's pretty simple to do it by hand, but I can't come up with any logic that automates this process
Assuming the possibility of a timestamp being the next bigger time to more than one trigger time it is allowed to overwrite an already assigned job value.
Create example code
CREATE TABLE [BigTable](
[timestamp] [datetime] NOT NULL,
[mode] [varchar](20) NOT NULL,
[ID] [smallint] NOT NULL,
[job] [smallint] NULL,
)
Insert Into [BigTable] values
('2022-05-30T09:15:18.907','abc',65,Null),
('2022-05-29T09:07:12.980','abc',64,Null),
('2022-05-28T09:02:00.977','abc',63,Null),
('2022-05-27T09:12:24.677','abc',62,Null)
CREATE TABLE [SmallTable](
[trigger] [datetime] NOT NULL,
[job] [smallint] NOT NULL,
)
Insert Into [SmallTable] values
('2022-05-30T09:05:05.000',1910),
('2022-05-29T09:13:12.000',1611)
details aren't consistent in your question - desired result and test code data...
used samples from the tables.
anyways, you can tweak a bit if necessary
select b.*, c.*
from bigtable as b
outer apply (
select top 1
s.job
from smalltable as s
where b.[timestamp] > s.[trigger]
) c

SQL Server composite key custom Auto Increment in child field

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.

How can I create a view that does a joins a table to itself and gives a means to select based on a key value

I have the following table DDL:
CREATE TABLE [dbo].[Test] (
[UserId] NVARCHAR (128) NOT NULL,
[TestId] INT IDENTITY (1, 1) NOT NULL,
[ExamId] INT NOT NULL,
[Title] NVARCHAR (100) NULL,
[Status] INT NOT NULL,
[CurrentQuestion] INT DEFAULT ((999)) NOT NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([TestId] ASC)
);
This table contains:
A list of ALL Exams and Tests that are available. These rows have a UserId = 0
A list of Exam and Test that are in progress for a particular user (UserId != 0)
A user may have one or may have multiple rows in this table.
Is there a way that I can create a view that shows a list of all the tests and where it exists the additional information for a user if that user has started a test. I'm really not sure if this needs to be a view or a stored procedure as it would need to take as input a UserId.
For the UserId = 1 who in this example has started two of the available tests:
ExamId TestId Title Status
1 1 Exam1Test1 Started
1 2 Exam1Test2
2 3 Exam1Test3 Started
2 4 Exam1Test4
or for the UserId = 2 who in this example has started three of the available tests:
1 1 Exam1Test1 Started
1 2 Exam1Test2
2 3 Exam1Test3 Started
2 4 Exam1Test4 Started
Your schema implies that any given test may be taken by at most one user at a time.
The query that will return the results you want is:
select
ExamId,
TestId,
Title,
case when userId = ? then "Started" else "" end as Status
from Tests
Of course you would replace the ? in the query with the actual user you're interested in.

How to re-number T-SQL's system auto-increment Identity column?

I have an auto-increment primary key in a SQL table lets say table look like this:
CREATE TABLE [Table] (--Identifier contains a space and uses a reserved keyword.
[ID] [int] IDENTITY(1,1) NOT NULL ,
[Name] [varchar](50) NULL,
CONSTRAINT [PK__Table] PRIMARY KEY CLUSTERED ([ID] ASC)
);
ID | Name|
1 John
2 Jack
3 Bill
4 Joe
Then I delete row 2 Jack:
ID | Name|
1 John
3 Bill
4 Joe
And what I want to achieve is to change id column so the table will look like this
ID | Name|
1 John
2 Bill
3 Joe
Is there a way to do it?
I will never do that but you can:
create a new autoincrement primary key named ID2
delete ID column
rename ID2 column as ID
Quick and dirty way to do it is, (my way) -->
select * into yournewtable from youroldtable order by yourIdentityColumn;
Then, open up yournewtable's design, make sure yourIdentityColumn is Identity(1,1).
Then, drop youroldtable.
Then, rename yournewtable to youroldtable! ta-da!
Set identity_insert Table off;
Update Table set ID = 3 where ID = 4;
...
Set identity_insert Table on;
Where Table name is Table

A table that has relation to itself issue

I've defined table with this schema :
CREATE TABLE [dbo].[Codings]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [int] NULL,
[CodeId] [int] NOT NULL,
[Title] [nvarchar](50) COLLATE Arabic_CI_AI NOT NULL,
CONSTRAINT [PK_Codings]
PRIMARY KEY CLUSTERED ([Id] ASC) WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
And fill it up with data like this :
Id ParentId CodeId Title
----------- ----------- ----------- ----------
1 NULL 0 Gender
2 1 1 Male
3 1 2 Female
4 NULL 0 Educational Level
5 4 1 BS
6 4 2 MS
7 4 3 PHD
Now I'm looking for a solution, in order, when I delete a record that is parent (like Id = 1 or 4), it deletes all children automatically (all records that have a ParentId = 1 or 4).
I supposed I can do it via relation between Id and Parent Id (and set cascade for delete rule), but when I do that in MMS, the Delete Rule or Update Rule in Properties is disabled.
My question is: what can I do to accomplish this?
Thank you
Edit:
When I wrote (like Id = 1 or 4) I meant the records that are parent, not a child, and I don't mean query like like Id = 1 or 4
Some friend implied I can do it via a delete trigger, but I supposed I can do it via relation
Maybe you have to define a index on the ParentID column first. You can't put constraints on columns that aren't indexed.
I always script for solutions to this, IE in the application search for the ID, then delete where all parent IDs = ID, then delete the parent record.
You can accomplish it with a "DELETE TRIGGER" - just use it to delete any rows that have matching parents. It's essentially the same thing a cascade-delete would do.
CREATE TRIGGER t_Codings_delete
ON Codings
AFTER DELETE
AS
BEGIN
DELETE Codings
FROM Codings c
JOIN DELETED d -- Virtual table containing rows you just deleted
ON c.ParentId = d.Id
END
How about an OR clause?
Delete From TableName
Where ID = 4 OR ParentId = 4
I don't think you can have cascading deletes on a self-refrencing table. You can probably do it with a join.
Delete from codings
inner join codings2 on codings.id = codings2.parentid
where codings.id = myid
Note not tested.