SQL Query to add Previous Data - sql

I have to write stored procedure (or SQL Query) in SQL server where in I will have 2 columns namely Month and count. Count value represents number of documents which is already present in the same table where in these 2 columns present.
In month column, there will be 12 months and in count column , I want , addition of number of documents in that month and number of documents till previous month.For e.g.In january I have 20 documents and in Feb there are 10 documents then this Stored Procedure will return me 20+10=30 documents for February Month and likewise.How can I achieve this.

Based on the partial information you have provided, following pseudo code should help:
create table t1 ( month int, [countdocs] int)
insert into t1 values (1,20),(2,10)
SELECT Cur.month, isnull(Cur.countdocs,0) + isnull(Prv.countdocs,0) AS countdocs
FROM t1 AS Cur
LEFT OUTER JOIN t1 AS Prv
ON Cur.month = Prv.month + 1;

Look up windowing functions in SQL server. You appear to want a running total and there are techniques to get those from windowing fn.

Related

How to compare records in the same table using SQL to find difference?

I want to compare two dispense transactions and find out if same drug was dispensed twice within 5 day window. How can I write SQL to compare these transactions and report?
patient_id
doctor_id
rx_number
pharmacy_id
drug_id
ship_date
1234
1234
rx_1234
ph_1234
1234
2022-06-28
1234
1234
rx_1234
ph_1234
1234
2022-07-01
EXISTS clause can be used for this purpose:
This one returns the row from the table if there is another row for the same drug within 5 days of ship_date:
select *
from MyTbl T1
where exists
(select *
from MyTbl T2
where T2.drug_id=T1.drug_id
and abs(datediff(day,T1.ship_date, T2.ship_date))<=5
)
The syntax for the 'number of days between two dates' is for SQL Server and it can change from one RDBMS product to other. You didn't specify what you use.
This query returns both rows (the earlier and the later shipment); you didn't specify the desired output.
I assumed ship_date=dispensed date.

How to create or generate this pattern in sql server( or in asp.net ) for reference ID [duplicate]

This question already has answers here:
In SQL Server how do I generate an auto-increment primary key ID that consists of year , a special char and a sequential series no.?
(2 answers)
Database scheme, autoincrement
(2 answers)
Closed 4 years ago.
I have to create reference Id , which has the following pattern and store it in
in referenceID column at tblReferences table
First month
H01C01001L
H01C01002L
...
H01C01102L
after a month the pattern repeats like this,
H01C02001L
H01C02002L
...
H01C02102L
third month:
H01C03001L
H01C03002L
...
H01C03102L
H01 C, and L will not change
upper limit for the sequence in pattern is unknown, but it will stop between 200 and 400 in a month
i am new to sql databases, any suggestion is appreciated.
You can use sequences to achieve that. Just create a new one that starts with your first number:
CREATE SEQUENCE dbo.NumbersSequence AS INT START WITH 1001 INCREMENT BY 1;
When you need to generate a new reference ID, obtain the next number from the sequence and format it to match your pattern:
declare #number int
select #number = NEXT VALUE FOR dbo.NumbersSequence;
select CONCAT('N01C', FORMAT(#number, 'D5'), 'L')
When you need to change the next value that will be generated (i.e. next month), alter the sequence:
ALTER SEQUENCE dbo.NumbersSequence RESTART WITH 2001;
Here's how I'd approach this. I assume a source table called sourcetable, having a date field named datefield:
insert into tblReferences (referenceID,...(other cols)...)
select
'H01C'
+convert(char(2),q2.monthindex)
+convert(char(3),row_number() over (partition by q2.monthindex order by s.datefield asc))
+'L' as referenceID,
...(other cols)...
from sourcetable s
cross join (select min(s2.datefield) as firstdate from sourcetable s2)q1 -- gets first date to compare others
cross apply(select datediff(month,q1.firstdate ,s.datefield as monthindex)q2 -- gets month difference between first and current
You may run the query without the first (insert) line to make sure it produces what you want. As others have commented, this won't work for more than a year, returning values like H01C13001L and so on.

SQL Server Inner Join with Timestamps: is each record only assigned once?

I am working with timestamped records and need to do an inner join based on the timestamp difference. I have been using the DATEDIFF function and it seems to be working well. However, the amount of time between timestamps varies. To clarify, sometimes the record appears in table 2 within the same second as table 1, and sometimes the record in table 2 is up to 15 seconds behind the record in table 1. The records in table 1 are always timestamped before table 2. There is no other common field with which I can join, however there is a register number in each table that I am using to increase accuracy by ensuring that the registers are the same.
My question is: if I increase the timestamp difference to do the inner join (e.g. where the DATEDIFF = 1 or 2 or 3... or 15) will records only be joined once? Or would my table contain duplicate records from table 1 (e.g. where record 1 is joined to record 4 in table 2 where the diff is 4 seconds, and is also joined with record 7 from table 2 where the diff is 11 seconds)?
The reason my statement works now is that no registers have records with less than 6 seconds in between, so even if there are multiple timestamps that would match, the matching of registers eliminates this problem.
My Statement is currently working as:
SELECT *
INTO AtriumSequoiaJoin5
FROM Atrium INNER JOIN Sequoia ON Atrium.Reader = Sequoia.theader_pos_name
WHERE (
((DateDiff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=0
Or (DateDiff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=1
Or (DateDiff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=2
Or (DateDiff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=3
Or (DateDiff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=4
Or (Datediff(s,[Atrium].[Date2],[Sequoia].[theader_tdatetime]))=5)
)
ORDER BY Sequoia.theader_id;
you could CROSS APPLY to the closest record in proximity. That's by no means ideal however, what if there are multiple records written at the same time? You perhaps should give the first table an identity field, then update the next table with scopeidentity
SELECT *
INTO AtriumSequoiaJoin5
FROM Atrium CROSS APPLY
(SELECT TOP 1 * FROM Sequoia WHERE
Atrium.Reader = Sequoia.theader_pos_name
ORDER BY Datediff(millisecond,[Atrium].[Date2],[Sequoia].[theader_tdatetime])) DQ
ORDER BY Sequoia.theader_id;

Sql query to check if the table value exists between range of dates

I am working in SQLServer database. I have the following scenario,
My application runs every weekday of the month, when it runs it puts an entry into the table 'CONTROL' into the 'businessDate' column.
Is there a way to find out what are the days the application did not run for a given month. Is it possible to achieve it in a single query ?
You need a calendar table. Then select from that table left joined to your CONTROL table on date, where the month is what you're looking for, and where the control table is null (to show just exclusions).
DECLARE #Month int = 1 //For January
SELECT BaseDate
FROM CalendarTable cal
LEFT OUTER JOIN ControlTable con
ON cal.BaseDate = con.businessDate //make sure to cast as a date if it's a datetime
WHERE MONTH(cal.BaseDate) = #Month
AND con.businessDate IS NULL

Filling one table using another table in SQL Server

I have two SQL tables as follows:
As you may note, the first table has a monthly frequency (date column), while the second table has a quarterly frequency. Here is what I would like to do:
For each issueid from table 1, I would like to look at the date, determine what is the previous end of quarter, and go fetch data from table 2 corresponding to that issue for that end of quarter, and insert it in the first table in the last two columns.
For example: take issueid 123456 and date 1/31/2014. The previous end of quarter is 12/31/2013. I would like to go to table 1, copy q_exp and q_act that correspond to that issueid and 12/31/2013, and paste it into the first table.
Of course, I would like to fill the entire first table and minimize manual inserts.
Any help would be appreciated! Thanks!
Try the following query
UPDATE issues
SET q_exp=(SELECT TOP 1 q.q_exp
FROM quarterlyTable q
WHERE q.issueid=i.issueid
AND q.[date]<=i.[date]
ORDER BY q.[date] DESC)
,q_act= (SELECT TOP 1 q.q_act
FROM quarterlyTable q
WHERE q.issueid=i.issueid
AND q.[date]<=i.[date]
ORDER BY q.[date] DESC)
FROM issues i