I have an MS access project in which the tabel of transactions contains as many as 70 records per day. they are common in one parameter, the Date of today.
the normal way to start entering data is to go to teh table and copy records of yesterday then paste them as new records, then changing date from yesterday to today date.
What I need is to use SQL statements to achieve this. I can say that
step 1: use insert into to input the new records in the table.
Step 2: use update statement to change the date.
Step 3: use the select statement to select the records which will have the date to be changed.
How to combine the use of these statements altogther.
thanks
You need something on the lines of:
INSERT INTO Table (Field, Field, Field, ADate)
SELECT Field,Field,Field,Date() As ADate
FROM Table WHERE ADate = Date()-1
Or just change the default value of the date field in the table to Date(), or Now(), and only insert the other fields. Date will then be automatically filled in as today.
Related
I have spent many hours researching this problem and trying various solutions but I never quite find a suitable solution for my specific problem. I am new to SQL and some of the examples are confusing as well.
So here is my dilemma. I have a equipment table that tracks oil changes for specific units in a database. The table looks like this:
**id UnitID Posted_On Date_Completed Note OverDueBy**
1 BT-109F 2019-02-04 2019-02-14 Hrs Overdue 23
1 BT-108G 2020-01-17 2020-01-22 Days Overdue 12
1 BT-122K 2020-01-02 2020-01-16 Days Overdue 12
1 BT-109F 2019-02-04 Days Overdue 3
The example records above need to be created or updated by the query. The date completed is entered manually by the technician when he has completed the oil change.
What I want the query to do is, Check to see if a specific Unit has a record where the 'Date_Completed' field is empty, and if so update the 'OverDueBy' field to reflect the new value. If all the records for the specified Unit have the 'Date_Completed' fields filled in, then the query should create a new record will all fields filled in except for the 'Date_Completed' field.
Can anyone help me construct such a query?
Thanks
Clan
First create a unique partial index for the column UnitID:
CREATE UNIQUE INDEX idx_unit ON tablename(UnitID)
WHERE Date_Completed IS NULL;
so that only 1 row with Date_Completed=null is allowed for each UnitID.
So a statement like this:
INSERT INTO tablename(id, UnitID, Posted_On, Date_Completed, Note, OverDueBy)
VALUES (?, 'BT-109F', ?, null, ?, ?)
ON CONFLICT(UnitID) WHERE Date_Completed IS NULL DO UPDATE
SET OverDueBy = ?;
will insert the new values only if there is no row already for UnitID='BT-109F' with null in Date_Completed.
But if there is such a row then it will update the column OverDueBy.
I'm not sure what values you want to insert or what will be the updated value so replace the ? with the appropriate values.
Firstly I would use a view rather than a table to store any calculated data - it reduces storage overheads and will update the calculation every time the view is opened.
If you're using SQLite you should be able to get the overdue by subtracting the Posted_On from its function to return today's date something like date('now') or julianday('now') - read up on and test the functions to ensure it does what you want.
So along the lines of:-
create view MyView as select *, julianday('now') - julianday(Posted_On) as OverDueBy from ClansTable where Date_Completed is null;
If you want to store a snapshot you can always create a table from a view in any case:-
create table MyStoredOverduesOn4thFeb as select * from MyView;
You can find your units that have all Date_Completed and create a single new record like so:-
Create table CompletedUnits as select id, UnitID, max(posted_on) as latest_posted_on, '' as Date_Completed from ClansTable group by id, UnitID having count(*) = count(Date_Complete);
Test this SQL and see if you can get it working - note I've created a text field for the date. Apparently there is no date/datetime data type as such:-
https://www.sqlitetutorial.net/sqlite-date/
Hope this helps,
Phil
I think you need something like this:
MERGE INTO EQUIPMENT A
USING (SELECT * FROM EQUIPMENT B WHERE DATE_COMPLETED IS NULL) C
ON (A.UNITID=C.UNITID)
WHEN MATCHED THEN UPDATE SET A.OVERDUEBY="new value"
WHEN NOT MATCHED THEN INSERT (A.id,A.UnitID,A.Posted_On,A.Date_Completed,A.Note,A.OverDueBy)
VALUES (C.id,C.UnitID,C.Posted_On,NULL,C.Note,C.OverDueBy)
Not sure where new values from update will come from. It's not clear in your question. But something like this could work.
I have a SQL Server table with just 3 columns, one of which is of type varbinary. The data in this column is actually a Json document which among other properties contains information about when the data was last modified. Unfortunately the SQL table itself does not contain information about when its rows were modified.
Now when doing sorting and filtering of the data I of course don't want fetch all rows in order to find e.g. the latest 100 entries.
So my question is: does SQL Server somehow remember when a row was added/modified? I have tried adding a timestamp and this is applied to all existing rows but this is applied randomly I think, because the sorting doesn't work. I don't need a datetime or anything, I just want to be able sort the records based on when they were last modified.
Thanks
For those looking to insert a tamestamp column of type DateTime into an existing DB table, you can do this like so:
ALTER TABLE TestTable
ADD DateInserted DATETIME NOT NULL DEFAULT (GETDATE());
The existing records will automatically get the value equal to the date/time of the moment when column is added.
New records will get up-to-date value upon insertion.
SQL Server will not track historically when a row was inserted or modified so you need to rely on the JSON data to figure that out yourself. You are going to need a new column to make this efficient to query. Once you have your new column you have some options:
Loop through all your records populating the new column with the relevant value from the JSON data.
If your version of SQL Server is recent enough, you can query the JSON data directly. Populate this column using a query like this:
UPDATE MyTable
SET MyNewColumn = JSON_VALUE(JsonDataColumn, '$.Customer.DateCreated')
The downside of this method is that you need to maintain this
Make SQL Server compute the value from the JSON automatically, for example:
ALTER TABLE MyTable
ADD MyNewColumn AS JSON_VALUE(JsonDataColumn, '$.Customer.DateCreated')
And, create an index to make it efficient:
CREATE INDEX IX_MyTable_MyNewColumn
ON MyTable(MyNewColumn)
Use a new column CreatedDate and store datetime every time you make an Insert.
You could use GetDate() for inserting date in the column.
A UpdatedDate column can be used for updates.
in order to find e.g. the latest 100 entries.
Timestamp is indeed what you need.
It's ever-increasing value, it's updated automatically, so you are always able to find all last modified/inserted rows.
Here is an example:
create table dbo.test1 (id int);
insert into dbo.test1 values(1), (2), (3);
alter table dbo.test1 add ts timestamp;
update dbo.test1
set id = 10
where id = 2
select top 1 *
from dbo.test1
order by ts desc;
--id ts
--10 0x000000001FCFABD2
insert into dbo.test1 (id)
values (100);
select top 1 *
from dbo.test1
order by ts desc;
--id ts
--100 0x000000001FCFABD3
As you see, you always get the last modified/inserted row.
For your purpose just use
select top 100 *
...
order by ts desc;
Thanks. Apparently I didn't look hard enough before I posted this question. The question has been asked a couple of times before and the answer is: Nope! There is no easy solution to this.
SQL Server does not keep track of when a record was created or modified, which was somehow what I was looking for. So I will go for the next best solution, which is probably to create a datetime column, retrieve the modified date from the Json document and then update the record. Or rather, the 1,4 million records:-(
I am using MS SQL Server 2008 and I have an sql table with some data that is inserted daily at 6 am by an sql job. The problem I have is that some data has been inserted separately into the job and I need to know when this data was added.
Is there a query I can run that will show me this?
I think the short answer is NO, there's no magic, ad hoc SQL query that will let you go back after the fact and find out when a row was inserted.
If you want to know when a row is inserted, the easiest thing would be to simply add a date or timestamp field with a default value (like getDate()) that automatically fills in the date/time when the row is inserted.
There are, of course, SQL logs available that will let you track when rows are inserted, updated, deleted, etc., but those require set up and maintenance.
Third option would be to have the program that's inserting the data perform some logging.
Add a date field to the table. You can give it a default value of GETDATE()
Then ORDER BY that field.
SELECT Column1, Column2, NewDateColumn
FROM YourTable
ORDER BY NewDateColumn
what i would do is :
/* add new column to keep inserted row date */
ALTER TABLE [schemaName].[tableName] ADD [RecTime] DATETIME;
/* update the existing rows with the current date since there is no way to guess their insertion date */
UPDATE [schemaName].[tableName] SET [RecTime] = GETDATE();
/* and set a constraint to the RecTime column to set current date on every new row added */
ALTER TABLE [schemaName].[tableName] ADD CONSTRAINT [DF_tableName_RecTime] DEFAULT (GETDATE()) FOR [RecTime]
then you can get those rows like :
SELECT *
FROM [schemaName].[tableName]
WHERE NOT(DATEPART(hh, RecTime) = 6 AND DATEPART(mi, RecTime) <= 20)
you can 'play' with '20' if you know how long sql job run
you probably need to look at SQL CREATE TRIGGER to add the logic to know when the data is being added and log that info in another table for further actions. Without further details I am not sure we can say more than that.
As you're referring to data which has already been inserted, the answer is No, unless you already have a datetime column which has a default value of GETDATE(). The best you can manage after the event has occurred is to look at the sequence of rows and determine that it was between two known times.
Hi I have one button named "Pay". User click so many times this button. Everytime it will create the current date in the column date in the table purchase.
How to do this in sql server 2008? Any hope?
To insert a record with corrent timestamp you can write a sql width CURRENT_TIMESTAMP as follows:
INSERT INTO Orders (date) VALUES(CURRENT_TIMESTAMP)
If you have other columns ont the Orders table, your SQL will go like as follows:
INSERT INTO Orders (date,....) VALUES(CURRENT_TIMESTAMP,.....)
This function CURRENT_TIMESTAMP is the ANSI SQL equivalent to GETDATE(), and you can also write this as fllows:
INSERT INTO Orders (date) VALUES(GETDATE())
The document is here.
http://msdn.microsoft.com/en-us/library/ms188751(v=sql.90).aspx
while inserting into table insert this value for the column where you want to save current date details DateTime.Now
I need to create a stored procedure that upon exceution checks if any new rows have been added to a table within the past 12 hours. If not, an warning email must be sent to a recipient.
I have the procedures for sending the email, but the problem is the query itself. I imagine I'd have to make an sql command that uses current date and compares that to the dates in the rows. But I'm a complete beginner in SQL so I can't even use the right words to find anything on google.
Short version:
Using MS SQL Server 2005, how can I check against the dates, then return a result based on whether new rows were created within the last 12 hours, and use that result to decide whether or not to send email?
Something like this should do what you wish.
Select ID
from TableName
where CreatedDate >= dateadd(hour,-12,getDate())
Hope this is clear but please feel free to pose further questions.
Cheers, John
Say your date field in the table is 'CreateDate' and it's of type DateTime.
Your time to compare with is: GETDATE()
(which returns date + time)
To get the datetime value of 12 hours before that, is done using DATEADD:
DATEADD(hour, -12, GETDATE())
so if we want the # of rows added in the last 12 hours, we'll do:
SELECT COUNT(*)
FROM Table
WHERE CreateDate >= DATEADD(hour, -12, GETDATE())
in your proc, you've to store the result of this query into a variable and check if it's > 0, so:
DECLARE #amount int
SELECT #amount=COUNT(*)
FROM Table
WHERE CreateDate >= DATEADD(hour, -12, GETDATE())
and then you'll check the #amount variable if it's > 0.
You could use a trigger, this link has several examples: http://msdn.microsoft.com/en-us/library/aa258254(SQL.80).aspx
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail 'MaryM',
'Don''t forget to print a report for the distributors.'
GO
If you do not want something for each insert/update, you could copy data to a another table then examine that table every 12 hours, report on the rows in it, then delete them...
assuming you have on this table :
- either a unique id autoincrementing
- either a created_timestamp field containing the timestamp of creation of the row
-> have a new table
reported_rows
- report_timestamp
- last_id_seen
(OR)
- last_timestamp_seen
fill the reported row each time you send your email with the actual value
and before sending the email, check with the previous values, so you know what rows have been added
If the table has an identity field, you could also save the max value (as a bookmark) and next time check if there are any rows with an ID greater than your saved bookmark. May be faster if the key is the clustered key.