Bypass duplicate record when one table data is inserted from another in SQL Server - sql

I am trying to insert data from one database table to another database table. This work is performed very well but need bypass that duplicate data cannot be inserted. Here is my query below. How can I check duplicate record?
;WITH ABC AS (
SELECT
5 AS DeviceID
, nUserID AS CardNo
, CONVERT(DATE, dbo.fn_ConvertToDateTime(nDateTime)) AS InOutDate
, CONVERT(VARCHAR(8) ,CONVERT(TIME,dbo.fn_ConvertToDateTime(nDateTime))) AS InOutTime
FROM [BioStar].[dbo].[TB_EVENT_LOG]
)
SELECT * INTO #tempAtten FROM ABC
INSERT [HR].[dbo].[HR_DeviceInOut](DeviceID, CardNo, InOutDate, InOutTime, ShiftprofileID, ExecutedBy)
SELECT DeviceID, CardNo, InOutDate, InOutTime, NULL, NULL
FROM #tempAtten
WHERE #tempAtten.InOutDate = CONVERT(DATE, GETDATE()) AND #tempAtten.CardNo <> 0
DROP TABLE #tempAtten
--HR_DeviceInOut
CREATE TABLE [dbo].[HR_DeviceInOut](
[id] [bigint] IDENTITY(100000000000001,1) NOT NULL,
[DeviceID] [nvarchar](20) NULL,
[CardNo] [nvarchar](20) NOT NULL,
[InOutDate] [date] NOT NULL,
[InOutTime] [nvarchar](10) NOT NULL,
[ShiftprofileID] [tinyint] NULL,
[ExecutedBy] [int] NULL,
CONSTRAINT [PK_HR_AttenHistory] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--Function
ALTER FUNCTION [dbo].[fn_ConvertToDateTime] (#Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
DECLARE #LocalTimeOffset BIGINT
,#AdjustedLocalDatetime BIGINT;
SET #LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
SET #AdjustedLocalDatetime = #Datetime - #LocalTimeOffset
RETURN (SELECT DATEADD(second,#AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;

Assuming I'm understanding correctly, here's one option using not exists:
INSERT [HR].[dbo].[HR_DeviceInOut] (DeviceID, CardNo, InOutDate,
InOutTime, ShiftprofileID, ExecutedBy)
SELECT DeviceID, CardNo, InOutDate, InOutTime, NULL, NULL
FROM #tempAtten t
WHERE t.InOutDate = CONVERT(DATE, GETDATE()) AND
t.CardNo <> 0 AND
NOT EXISTS (
SELECT 1
FROM [HR].[dbo].[HR_DeviceInOut] d
WHERE t.DeviceID = d.DeviceId AND
t.CardNo = d.CardNo AND
t.InOutDate = d.InOutDate AND
t.InOutTime = d.InOutTime
)
Consider adding a unique_index to the those fields that cannot be duplicated.

Which column set make record unique as i see some column are hard coded
ie 5 AS DeviceID ...
Create unique key for rest of the column in temp table and destinationtabel.to avoid duplicate .

Related

Why calculated fields using scalar functions are slow

I have below table:
CREATE TABLE [dbo].[Client](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](150) NOT NULL,
[InternalSiteId] AS (isnull(CONVERT([int],[dbo].[GetCurrentTemporalValue]([Id],'Client_InternalSite')),(0))),
[BudgetingStatusId] AS (isnull(CONVERT([int],[dbo].[GetCurrentTemporalValue]([Id],'Client_BudgetingStatus')),(1))),
[BusinessUnitId] AS (isnull(CONVERT([int],[dbo].[GetCurrentTemporalValue]([Id],'Client_BusinessUnit')),(0))),
CONSTRAINT [PK_dbo.Client] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
which has 3 calculated fields using scalar function:
CREATE FUNCTION [dbo].[GetCurrentTemporalValue]
(
#clientId INT,
#temporalType NVARCHAR(128)
)
RETURNS NVARCHAR(255)
AS
BEGIN
DECLARE #retVal INT
DECLARE #at DATETIME
SET #at = GETUTCDATE()
SELECT #retVal = CAST(Value AS INT) FROM dbo.Temporal
WHERE 1 = 1
AND ClientId = #clientId
AND TemporalType = #temporalType
AND ( ValidFrom <= #at OR ValidFrom IS NULL )
AND ( ValidTo >= #at OR ValidTo IS NULL)
RETURN #retVal
END
GO
and this function uses below table:
CREATE TABLE [dbo].[Temporal](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ClientId] [int] NOT NULL,
[Value] [nvarchar](255) NULL,
[ValidFrom] [datetime2](7) NULL,
[ValidTo] [datetime2](7) NULL,
[TemporalType] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_dbo.Temporal] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
The Client table has around 2500 records but the select * from [Client] takes about 14 seconds!
When I comment these 3 calculated fields, it gets back to normal value below one second. So the scalar function seems to cause the issue.
I tried to make condition easier ( left only 1 = 1 ) but it didn't change the speed.
What I want to achieve is:
historical values (kept in Temporal table)
current value to be pointed out by Client.InternalSiteId, Client.BudgetingStatusId and Client.BusinessUnitId
I cannot just simply make InternalSiteId a regular int fields with foreign key to, let say, InternalSiteHistoryTable as there are ValidFrom and ValidTo fields pointing out the period in which given value is valid and current and e.g. ValidFrom can be set to future value. That's why I need such calculations in function to find out current value.
What should I do / change to achieve above goals, but keep the reasonable fetching data speed?
Use a view to join to your Temporal table instead of embedding function calls
-- Table without those functions to slow things down
CREATE TABLE [dbo].[ClientName](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](150) NOT NULL,
CONSTRAINT [PK_dbo.Client] PRIMARY KEY CLUSTERED
(
[Id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF)
ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
--instead, use a view to do the same thing
CREATE VIEW [dbo].[Client] as
SELECT
ClientName.Id,
ClientName.Name,
isnull(CONVERT([int], Client_InternalSite.Value), 0) AS InternalSiteId,
isnull(CONVERT([int], Client_BudgetingStatus.Value, 1) AS BudgetingStatusId,
isnull(CONVERT([int], Client_BusinessUnit.Value, 0) AS BusinessUnitId
FROM ClientName INNER JOIN
( SELECT Value, ClientId
FROM Temporal
WHERE TemporalType='Client_InternalSite'
AND ( ValidFrom <= GETUTCDATE() OR ValidFrom IS NULL )
AND ( ValidTo >= GETUTCDATE() OR ValidTo IS NULL)
) AS Client_InternalSite ON ClientName.ID = Client_InternalSite.ClientID
INNER JOIN
( SELECT Value, ClientId
FROM Temporal
WHERE TemporalType='Client_BudgetingStatus'
AND ( ValidFrom <= GETUTCDATE() OR ValidFrom IS NULL )
AND ( ValidTo >= GETUTCDATE() OR ValidTo IS NULL)
) AS Client_BudgetingStatus ON ClientName.ID = Client_BudgetingStatus.ClientID
INNER JOIN
( SELECT Value, ClientId
FROM Temporal
WHERE TemporalType='Client_BusinessUnit'
AND ( ValidFrom <= GETUTCDATE() OR ValidFrom IS NULL )
AND ( ValidTo >= GETUTCDATE() OR ValidTo IS NULL)
) AS Client_BusinessUnit ON ClientName.ID = Client_BusinessUnit.ClientID
GO
I can't test this against your DB, so I don't know about your indexes on your Temporal table (ID, ValidFrom, ValidTo columns), but typically a VIEW like this is going to run quicker because the tables are queried only once.

How To Improve Performance of Sql Query with Union

Below query takes almost 47-50 seconds on our production server, but when I execute the same on a test server with the same database, it executes in less than a second.
CREATE TABLE [dbo].[Table0]
(
[UserID] [VARCHAR](20) NOT NULL,
[Key] [VARCHAR](600) NOT NULL,
[Type] [VARCHAR](20) NOT NULL,
[status] [VARCHAR](10) NOT NULL,
[RecID] [NUMERIC](18, 0) NOT NULL,
CONSTRAINT [PK_Table0]
PRIMARY KEY CLUSTERED ([UserID] ASC, [Key] ASC, [Type] ASC, [status], [RecID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Table2]
(
[UserID] [VARCHAR](20) NOT NULL,
[RecID] [NUMERIC](18, 0) NOT NULL,
[Activity] [NUMERIC](2, 0) NOT NULL,
[AwsExist] [NUMERIC](2, 0) NULL,
[View] [NUMERIC](2, 0) NULL,
CONSTRAINT [PK_Table2]
PRIMARY KEY CLUSTERED ([UserID] ASC, [RecID] ASC, [Activity] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Table3]
(
[UserID] [VARCHAR](20) NOT NULL,
[RecId] [NUMERIC](18, 0) NOT NULL,
[Activity] [NUMERIC](2, 0) NOT NULL,
[AwsExist] [NUMERIC](2, 0) NULL,
[RecDate] [DATETIME] NULL,
[View] [NUMERIC](2, 0) NULL,
CONSTRAINT [PK_Table3]
PRIMARY KEY CLUSTERED ([UserID] ASC, [RecId] ASC, [Activity] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Table0 contains 10,000 Records
Table1 contains 20,00,000 records
Table2 contains 25,00,000 records
which parameter should I check to resolve the issue? I just want to check if a record exists in one of these table for RecID
Select UserID From Table0 Where RecId = 56445 And Type = 'D'
Union
Select UserID From Table1 Where RecId = 56445 And View = 0
Union
Select UserID From Table2 Where RecId = 56445 And View = 0
I tried with this code:
DECLARE RecID AS INT
SET RecID = 56445
IF NOT EXISTS (SELECT DISTINCT TOP(1) USerID
FROM Table0
WHERE RecId = #RecID
AND Type = 'D')
BEGIN
IF NOT EXISTS (SELECT DISTINCT TOP(1) UserID
FROM Table1
WHERE RecId = #RecID AND View = 0)
BEGIN
SELECT DISTINCT TOP(1) UserID
FROM Table2
WHERE RecId = #RecID AND View = 0
END
END
but it also takes around 18 seconds.
This query should be fast -- assuming not many rows are returned:
Select UserID From Table0 Where RecId = 56445 And Type = 'D'
Union
Select UserID From Table1 Where RecId = 56445 And View = 0
Union
Select UserID From Table2 Where RecId = 56445 And View = 0;
What you need are indexes:
Table0(recid, type, userid)
Table1(recid, view, userid)
Table2(recid, view, userid)
You may have to use query like:
Select UserID
From table0
Where exists (
Select 1
From Table0 t0, Table1 t1, Table2 t2
Where (t0.RecId = 56445 and t0.Type= 'D') OR (t1.RecId = 56445 and t1.View= 0) OR (t2.RecId = 56445 AND t2.View=0))

SQL Server Count items available

I am building a pretty simple inventory items database that will allow me to check out items between dates. I will need to return a single row that will tell me the available, reserved, and total inventory of this item. I cannot seem to get this correct.
BEGIN TRAN
DECLARE #startDate AS DATE
DECLARE #endDate AS DATE
DECLARE #partID AS INT
SET #startDate = '4/15/2015'
SET #endDate = '4/25/2015'
SET #partID = 248
SELECT COUNT(ii.[PartId] WHERE ii.[PartStatus] = 1 ) AS [Available],
COUNT(ii.[PartId] WHERE ii.[PartStatus] = 2 ) AS [Reserverd],
COUNT(ii.[PartId] WHERE ii.[PartStatus] <> 4 ) AS [TotalInventory],
FROM ShipListInventory.dbo.InventoryItems AS ii
LEFT JOIN ShipListInventory.dbo.InventoryItemCalendars AS iic
ON iic.[ItemId] = ii.[Id]
WHERE iic.[StartDate] NOT BETWEEN #startDate AND #endDate
AND iic.[InboundDate] NOT BETWEEN #startDate AND #endDate
AND ii.[PartId] = 248
COMMIT TRAN
EDIT: I am only returning rows from InventoryItemCalendarsI want to return items from InventoryItems
CREATE TABLE [dbo].[InventoryItems](
[Id] [INT] IDENTITY(1,1) NOT NULL,
[PartSatuts] [INT] NOT NULL,
[PartId] [INT] NOT NULL,
[Barcode] [NVARCHAR](MAX) NULL,
[PicturePath] [NVARCHAR](255) NULL,
[Notes] [NVARCHAR](1000) NULL,
CONSTRAINT [PK_dbo.InventoryItems] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[InventoryItems] WITH CHECK ADD CONSTRAINT [FK_dbo.InventoryItems_dbo.Parts_PartId] FOREIGN KEY([PartId])
REFERENCES [dbo].[Parts] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[InventoryItems] CHECK CONSTRAINT [FK_dbo.InventoryItems_dbo.Parts_PartId]
GO
CREATE TABLE [dbo].[InventoryItemCalendars](
[Id] [INT] IDENTITY(1,1) NOT NULL,
[StartDate] [DATETIME] NOT NULL,
[InboundDate] [DATETIME] NOT NULL,
[ProjectNumber] [INT] NOT NULL,
[ItemId] [INT] NOT NULL,
[Project_Id] [INT] NULL,
CONSTRAINT [PK_dbo.InventoryItemCalendars] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[InventoryItemCalendars] WITH CHECK ADD CONSTRAINT [FK_dbo.InventoryItemCalendars_dbo.InventoryItems_ItemId] FOREIGN KEY([ItemId])
REFERENCES [dbo].[InventoryItems] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[InventoryItemCalendars] CHECK CONSTRAINT [FK_dbo.InventoryItemCalendars_dbo.InventoryItems_ItemId]
GO
ALTER TABLE [dbo].[InventoryItemCalendars] WITH CHECK ADD CONSTRAINT [FK_dbo.InventoryItemCalendars_dbo.Projects_Project_Id] FOREIGN KEY([Project_Id])
REFERENCES [dbo].[Projects] ([Id])
GO
ALTER TABLE [dbo].[InventoryItemCalendars] CHECK CONSTRAINT [FK_dbo.InventoryItemCalendars_dbo.Projects_Project_Id]
GO
INSERT INTO ShipListInventory.[dbo].[InventoryItems]([PartSatuts],[PartId]) VALUES(1,1);
INSERT INTO ShipListInventory.[dbo].[InventoryItems]([PartSatuts],[PartId]) VALUES(2,1);
INSERT INTO ShipListInventory.[dbo].[InventoryItems]([PartSatuts],[PartId]) VALUES(1,1);
INSERT INTO ShipListInventory.[dbo].[InventoryItems]([PartSatuts],[PartId]) VALUES(4,1);
INSERT INTO ShipListInventory.[dbo].[InventoryItemCalendars](StartDate,InboundDate,Project_Id, ItemId)VALUES('1/1/2015', '4/15/2015',1,1)
INSERT INTO ShipListInventory.[dbo].[InventoryItemCalendars](StartDate,InboundDate,Project_Id, ItemId)VALUES('1/1/2015', '4/15/2015',1,1)
INSERT INTO ShipListInventory.[dbo].[InventoryItemCalendars](StartDate,InboundDate,Project_Id, ItemId)VALUES('1/1/2015', '4/14/2015',1,2)
INSERT INTO ShipListInventory.[dbo].[InventoryItemCalendars](StartDate,InboundDate,Project_Id, ItemId)VALUES('1/1/2015', '4/15/2015',1,1)
this isnt returning data from correct table it is only returning data form InventoryItemCalendars which isnt what i want. i want it to only use this to check the dates. it should return the items from InventoryItems table
Here is a syntactically correct version:
SELECT SUM(CASE WHEN ii.[PartStatus] = 1 THEN 1 ELSE 0 END) AS [Available],
SUM(CASE WHEN ii.[PartStatus] = 2 THEN 1 ELSE 0 END) AS [Reserverd],
SUM(CASE WHEN ii.[PartStatus] <> 4 THEN 1 ELSE 0 END) AS [TotalInventory]
FROM ShipListInventory.dbo.InventoryItems ii LEFT JOIN
ShipListInventory.dbo.InventoryItemCalendars AS iic
ON iic.[ItemId] = ii.[Id]
WHERE iic.[StartDate] NOT BETWEEN #startDate AND #endDate AND
iic.[InboundDate] NOT BETWEEN #startDate AND #endDate AND
ii.[PartId] = 248;
There is no transaction when you do a select, so committing is not necessary.
SELECT COUNT(CASE WHEN ii.[PartStatus] = 1 THEN ii.[PartId] END) AS [Available],
COUNT(CASE WHEN ii.[PartStatus] = 2 THEN ii.[PartId] END) AS [Reserverd],
COUNT(CASE WHEN ii.[PartStatus] <> 4 THEN ii.[PartId] END) AS [TotalInventory]
With the help of Juan Carlos I have found the correct answer.
SELECT COUNT(CASE WHEN ii.[PartSatuts]=1 THEN ii.[PartId] END ) AS [Available],
COUNT(CASE WHEN ii.[PartSatuts]=2 THEN ii.[PartId] END ) AS [Reserverd],
COUNT(CASE WHEN ii.[PartSatuts]<> 4 THEN ii.[PartId] END ) AS [TotalInventory]
FROM ShipListInventory.dbo.InventoryItems AS ii
LEFT JOIN ShipListInventory.dbo.InventoryItemCalendars AS iic
ON iic.ItemId = ii.Id
WHERE ((iic.StartDate NOT BETWEEN #startDate AND #endDate
AND iic.InboundDate NOT BETWEEN #startDate AND #endDate)
OR iic.InboundDate IS NULL)
AND ii.PartId = 248

SQL Descending ordered LEFT JOIN subquery issue

I have the following query.
SELECT r1.*,
r2.vlag54,
r2.vlag55
FROM [rxmon].[dbo].[a] AS r1
LEFT JOIN [rxmon].[dbo].[b] AS r2
ON r2.artikelnummer = r1.drug_id
LEFT JOIN (SELECT *
FROM [rxmon].[dbo].[c]) AS r3
ON r3.pid = r1.patient_id
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
AND r1.patient_id = 7092425
AND obx_value < CASE
WHEN r2.vlag54 = 1 THEN 30
WHEN r2.vlag55 = 1 THEN 50
END
AND r2.vlag54 = CASE
WHEN r3.obx_value < 30 THEN 1
ELSE 0
END
AND r2.vlag55 = CASE
WHEN r3.obx_value BETWEEN 30 AND 50 THEN 1
ELSE 0
END
ORDER BY obx_datetime DESC;
The problem is that table C can contain multiple records based on de PID join. This generates the same records because of the multiple records on table C.
The table C needs to e joined as the latest record only so just 1 of C. That way the table A record will not be repeated.
I tried TOP 1 and order by but that can't be used in subquery.
-- TABLE A
CREATE TABLE [dbo].[A]
[EVS_MO_ID] [bigint] NOT NULL,
[DRUG_ID] [varchar](50) NOT NULL,
[ATC_CODE] [varchar](15) NULL,
[DRUG_NAME] [varchar](1024) NULL,
[PATIENT_ID] [varchar](50) NOT NULL,
[PATIENT_LOCATION] [varchar](10) NULL,
[MO_DATE] [datetime2](7) NOT NULL,
[MO_START_DATE] [datetime2](7) NOT NULL,
[MO_STOP_DATE] [datetime2](7) NULL,
[ROUTE] [varchar](50) NULL,
[MEDICATION_CONTAINER] [smallint] NULL,
[PRESCRIBING_DOCTOR_NAME] [varchar](50) NULL,
[PRESCRIBING_DOCTOR_SURNAME] [varchar](50) NULL,
[MO_ACTIVE] [bit] NOT NULL,
CONSTRAINT [PK_MedicationOrders] PRIMARY KEY CLUSTERED
(
[EVS_MO_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[A]
VALUES
(5411409,'97941689', 'B01AB06','NADROPARINE 0.8ML','7092425','ANBC', '2015-12-15 20:58:06.2030000',
'2015-12-16 00:00:00.0000000', '', 'IV', 1, 'GEORGE','LAST', 1);
-- TABLE B
CREATE TABLE [dbo].[B](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ARTIKELNUMMER] [varchar](50) NOT NULL,
[VLAG54] [bit] NULL,
[VLAG55] [bit] NULL CONSTRAINT [DF_Table_1_VLAG50] DEFAULT ((0)),
[VLAG100] [bit] NULL CONSTRAINT [DF_ArtikelVlaggen_VLAG100] DEFAULT ((0)),
CONSTRAINT [PK_B] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[B]
([ARTIKELNUMMER]
,[VLAG54]
,[VLAG55]
,[VLAG100])
VALUES
('97941689', 1,0,1);
-- TABLE C
CREATE TABLE [dbo].[C](
[ID] [int] IDENTITY(1,1) NOT NULL,
[OBX_DATETIME] [datetime2](7) NOT NULL,
[PID] [int] NOT NULL,
[DEPARTMENT] [varchar](8) NOT NULL,
[OBX_ID] [int] NOT NULL,
[OBX_VALUE] [decimal](5, 2) NOT NULL,
[OBX_UNITS] [varchar](10) NULL,
[REF_RANGE] [varchar](40) NULL,
[FLAG] [varchar](2) NULL,
CONSTRAINT [PK_C] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [dbo].[C]
([OBX_DATETIME]
,[PID]
,[DEPARTMENT]
,[OBX_ID]
,[OBX_VALUE]
,[OBX_UNITS]
,[REF_RANGE]
,[FLAG])
VALUES
('2015-12-15 14:01:00.0000000',7092425, '8NAH', 20937, 27.00, 'mL/min', '> 60', 'L');
INSERT INTO [dbo].[C]
([OBX_DATETIME]
,[PID]
,[DEPARTMENT]
,[OBX_ID]
,[OBX_VALUE]
,[OBX_UNITS]
,[REF_RANGE]
,[FLAG])
VALUES
('2015-12-15 06:30:00.0000000',7092425, '6ZPA', 20937, 28.00, 'mL/min', '> 60', 'L');
This will order them by OBX_DATETIME and take only the first one:
...
LEFT JOIN (
SELECT pid, obx_id, obx_datetime, obx_value
, n = ROW_NUMBER() over(PARTITION BY pid ORDER BY obx_datetime desc)
FROM [rxmon].[dbo].[c]
) AS r3
ON r3.pid = r1.patient_id and r3.n = 1
...
If OBX_DATETIME are inserted incrementaly (newer date only), you can order by ID instead.
This SQL Fiddle with your query and sample data/tables returns 2 rows: http://sqlfiddle.com/#!3/df36c/2/0
This SQL Fiddle with the new subquery returns 1 row: http://sqlfiddle.com/#!3/df36c/1/0
You are using a LEFT JOIN on r3 but have also have r3 in your WHERE clause with equal operator:
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
It will remove NULL value from the left join on r3. Perhaps you should also move it to the sub query or use INNER JOIN.
You should also avoind using the DB name in your query unless this query is run from another DB on the same server. This will be fine:
SELECT ... FROM [dbo].[a] AS r1 ...
Using SELECT * is also a bad habit. You should list only the columns your code will use.
try this.... #Shift
SELECT r1.*,
r2.vlag54,
r2.vlag55
FROM [dbo].[a] AS r1
LEFT JOIN [dbo].[b] AS r2
ON r2.artikelnummer = r1.drug_id
LEFT JOIN (
SELECT
ROW_NUMBER() OVER (PARTITION BY pid ORDER BY id DESC) RN,
c.*
FROM C
) r3
ON r3.pid = r1.patient_id AND r3.RN = 1
WHERE r3.obx_id = 20937
AND Cast(r3.obx_datetime AS DATE) = Cast(Getdate() - 1 AS DATE)
AND r1.patient_id = 7092425
AND obx_value < CASE
WHEN r2.vlag54 = 1 THEN 30
WHEN r2.vlag55 = 1 THEN 50
END
AND r2.vlag54 = CASE
WHEN r3.obx_value < 30 THEN 1
ELSE 0
END
AND r2.vlag55 = CASE
WHEN r3.obx_value BETWEEN 30 AND 50 THEN 1
ELSE 0
END
ORDER BY obx_datetime DESC;

Conversion failed when converting the nvarchar value 'newValue' to data type int

I'm pretty sure that I am inserting the correct data. I have drop all Indexes, Triggers, Constraint to make sure nothing is intervening my insert.
Here's the catch: the field that I'm trying to insert to previously has a datatype of int but changed to nvarchar(100) later. Does anybody know where should I look into?
This is the table structure
CREATE TABLE [dbo].[myTable.Values](
[myTableId] [bigint] NOT NULL,
[myTableCode] [nvarchar](100) NOT NULL,
[Code] [nvarchar](100) NOT NULL,
[value] [nvarchar](250) NOT NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
[UpdateById] [bigint] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
CONSTRAINT [PK_myTable.Values] PRIMARY KEY CLUSTERED
(
[myTableCode] ASC,
[Code] ASC,
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, `ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]`
) ON [PRIMARY]
and this is the script for insert
INSERT INTO [dbo].[myTable.Values] (
[myTableId]
,[myTableCode]
,[Code]
,[value]
,[UpdateById]
,[UpdateDate]
)
VALUES (
581
,'myParentTableCODE'
,'myTableNewCode'
,'myTableNewCode'
,5197
,getdate()
)
Thanks for looking into this, I have found out one of our View is using "WITH SCHEMABINDING" clause. And that view is Casting the field "Code" as int. Here is the view.
CREATE VIEW [dbo].[vSomeView] WITH SCHEMABINDING
AS
SELECT
id,
CAST(Code AS INT) AS [Code],
myTableCode
FROM dbo.[myTable.Values]
WHERE myTableCode LIKE '%ABC'
AND ISNUMERIC(Code) = 1
it seems yourinsertion code is not complete, you should to add another field and assign value to it,the field is IsDefaultObsolete, then try this code for insert :
INSERT INTO [dbo].[myTable.Values] (
[myTableId]
,[myTableCode]
,[Code]
,[value]
,[IsDefaultObsolete]
,[UpdateById]
,[UpdateDate]
)
VALUES (
581
,'myParentTableCODE'
,'myTableNewCode'
,'myTableNewCode'
0,--THIS MAY BE 0 OR 1 DEPENDING YOU
,5197
,getdate()
)