I have a database which contains 2 fields called DateOfBirth and Age, for storing users DOB and age respectively. I want the Age column to be automatically incremented by 1 every year, according to the DOB matching server date.
What could be the best way for achieving this? I am using asp.net and sql server 2008.
Rather than store both the DateOfBirth and Age, create a computed column on the table that calculates the age:
[Age] AS datediff(year, DateOfBirth, getdate())
So in yout table creation:
-- Create Table with computed column
CREATE TABLE [dbo].[CCtest]
(
[id] [int] not NULL,
[DateOfBirth] [datetime] NULL,
-- etc...
[Age] AS datediff(year, DateOfBirth, getdate())
)
GO
If you want to persist the computed value add the PERSISTED keyword.
One possibility, if you want Age displayed in years and months:
[AgeInDays] AS datediff(day, DateOfBirth, getdate())
then create a view over your table that formats AgeInDays into years and months.
Here is another possibility, using a computed column of [AgeYears]:
create view vwCCtestAge
AS
select
id,
dateofbirth,
cast([AgeYears] as varchar(4)) + ' years ' +
cast(datediff(month, DateOfBirth, getdate())
- case when (AgeYears > 0) then (AgeYears - 1)*12
else 0
end as varchar(4)) + ' months' as Age
from cctest2
GO
[You should check for boundary cases...]
Related
I know it works with following code in MySQL to achieve such goal:
set #n = 0;
select (#n := #n + 1),test_score from test_score where student_name = 'Gao' and test_subject = 'math'
In SQLite,there is no variable, so how can I implement similar function in SQLite?
Thanks!
Assuming you have an ID field in your test_score table you could just easily add ORDER BY ID ASC to your select query.
CREATE TABLE test_score (ID INTEGER AUTOINCREMENT, student_name TEXT, test_subject TEXT, score TEXT)
SELECT ID, score FROM test_score WHERE student_name='Gao' AND test_subject='math' ORDER BY ID ASC;
NB: by default the query would be ordered by the ID anyway, but in case you would want to switch it to the most recent just replace ASC with DESC
I have two tables Procedures and ProcedureTypes.
Procedures has a column Type which is a varchar with the values (1, 2), (3, 4), (4, 5) etc...
ProcedureType has a primary key 'ID' 1 to 9.
ID Description
1 Drug
2 Other-Drug
etc...
ID is an integer value and Type is varchar value.
Now I need to join these two tables to show the values
ID in the Procedures table
ProcedureType in the Procedures table
Description in the ProceduresType table with the value separated by a "-".
For example if he value in Type is (1,2) the new table after join should show values in the description like (Drug-Other Drug)
I have used this query bot to no avail
SELECT * FROM dbo.[Split]((select RequestType from GPsProcedures), ',')
Can anyone tell me how to do it and why the above query is not working
with Procedures as (
select 1 as ID, '1,2,3' as Typ
),
ProcedureTypes as (
select 1 as TypeID, 'Drug' as Name
union select 2 , 'Other-Drug'
union select 3 , 'Test 3'
)
/*Get one extra column of type xml*/
,Procedures_xml as (
select id,CONVERT(xml,' <root> <s>' + REPLACE(Typ,',','</s> <s>') + '</s> </root> ') as Typ_xml
from Procedures
)
/*Convert the field string to multiple rows then join to procedure types*/
, Procdure_With_Type as (
select ID,T.c.value('.','varchar(20)') as TypeID,
ProcedureTypes.Name
from Procedures_xml
CROSS APPLY Typ_xml.nodes('/root/s') T(c)
INNER JOIN ProcedureTypes ON T.c.value('.','varchar(20)') = ProcedureTypes.TypeID
)
/*Finally, group the procedures type names by procedure id*/
select id,
STUFF((
SELECT ', ' + [Name]
FROM Procdure_With_Type inn
WHERE (Procdure_With_Type.ID = inn.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
from Procdure_With_Type
group by ID
You can't have a select statement as a parameter for a function, so instead of this:
SELECT * FROM dbo.[Split]((select RequestType from GPsProcedures), ',')
Use this:
select S.*
from GPsProcedures P
cross apply dbo.[Split](P.RequestType, ',') S
ALTER PROCEDURE [dbo].[K_FS_InsertMrpDetails]
#date datetime,
#feedtype varchar(50),
#rateperkg float,
#rateper50kg float,
#updatedby varchar(50)
AS
BEGIN
INSERT INTO K_FS_FeedMrpDetails([date], feedtype, rateperkg, rateper50kg, updatedby, updatedon)
VALUES(#date, #feedtype, #rateperkg, #rateper50kg, #updatedby, getdate())
SELECT '1' AS status
END
With this query we insert 9 rows at a time but what I want is in one same date do not insert again different details. How can I please help me.
Add a unique constraint on the column [date]. That will prevent you from adding more than one row with the same [date] value.
Update:
To allow 9 rows for each date you can add a computed column D that removes the time part and you need to add a column that will hold the values 1 to 9 R. Use a check constraint on R to only allow 1-9. Finally you create a unique constraint on (R, D).
Sample table definition:
create table T
(
ID int identity primary key,
DT datetime not null,
R tinyint check (R in (1,2,3,4,5,6,7,8,9)) not null,
D as dateadd(day, datediff(day, 0, DT), 0),
constraint ux_RD unique (R,D)
)
Try with this:
insert into T(DT, R) values(getdate(), 1)
insert into T(DT, R) values(getdate(), 2)
insert into T(DT, R) values(getdate(), 1)
First and second insert works fine, the third raises a unique constraint exception.
Hi' I'm working with an asp.net application wich related to the registration of students, the data related to the students is inserted in to a database, each time a student is registered the field idStudent is incremented by one, what I want to do is when a new year begins reset the student value in order to begin from 1 in the new year.
idStudent Year 1 2011 2 2011 3
2011 4 2011 5 2011 ..... 1 2012 2
2012 3 2012 .......
How can I do this?
The databse is in sql server 2008
Hope your help
If I had this exact business requirement and I couldn't negotiate a better, more efficient way then this would be my approach:
Instead of using an artificial key (i.e. an identity column) I would utilize a composite key. To find out what your best bet for a composite key would be, you need to know the business rules and logic. In other words, a question you would have to ask is is the combination of year and id unique? In other words, per year a student id can only be used once...?
This is one of those times were you would benefit from a natural composite key.
You could add a computed column which derives the number based on the year. You just need to run the script below at the start of the new year. Do note that when a transaction is rolled back there will be gaps in the identity column. (and inserts in a previous year will create big gaps as well.)
-- test table & inserts
create table Students (Id int identity, year int, name varchar(20), StudentId int null)
insert into Students (year, name) values (2010, 'student1'), (2011, 'student1'), (2011, 'student2')
-- run this every year
EXEC ('ALTER TABLE Students DROP COLUMN StudentId ')
declare #count int, #sql varchar(max), #year int
declare c cursor local read_only
for select year + 1, max(Id) from Students group by year
open c
fetch next from c into #year, #count
select #sql = 'when year = ' + convert(varchar(10), #year - 1) + ' then Id '+ CHAR(13) + CHAR(10)
while ##FETCH_STATUS = 0
begin
select #sql = #sql + 'when year = ' + convert(varchar(10), #year) + ' then Id - ' + convert(varchar(10), #count) + CHAR(13) + CHAR(10)
fetch next from c into #year, #count
end
close c
deallocate c
select #sql = 'CASE ' + CHAR(13) + CHAR(10) + #sql + ' ELSE 0 END'
select #sql = 'ALTER TABLE Students ADD StudentId AS ' + isnull(#sql, 'Id') + ' PERSISTED'
exec (#sql)
I have a database table field named User_Created_Date of type Varchar.I want to write a query to fetch all records where the difference between Today's date and User_Created_Date is greater than 31 days
pls help
Since your VARCHAR column's date format is DD/MM/YY, use:
select * from Your_Table
where DATEDIFF(day, CONVERT(datetime, User_Created_Date, 3), GETDATE()) > 31;