I have an Employee table and how it works is, when a new employee is added, the column [DOR] will be null and [Status] will be 1. When the employee is being relieved from the company, the [DOR] column value will be the date which he/she left the company and [Status] is set to 0.
I need to fetch the details of all the employees who were available in a given date. The employees with Status as 1 and those who are not yet relieved till that date have to be fetched.
But I am not able to do the same as when equating with DOR, its null value and not returning any of the rows.
If I give the input as 2015-02-10, it should fetch the two records and when I give 2015-02-15, it should fetch only first record.
CREATE TABLE [Employee]
(
[EmployeeId] [int] IDENTITY(1000,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[RoleId] [int] NOT NULL,
[Email] [varchar](50) NULL,
[Contact] [varchar](50) NULL,
[DOJ] [date] NOT NULL,
[DOR] [date] NULL,
[Status] [bit] NOT NULL,
[Salary] [decimal](18, 2) NULL
)
INSERT [dbo].[Employee] ([EmployeeId], [Name], [RoleId], [Email], [Contact], [DOJ], [DOR], [Status], [Salary])
VALUES (1001, N'Employee 1', 3, N'', N'', CAST(0x8D390B00 AS Date), NULL, 1, CAST(6000.00 AS Decimal(18, 2)))
INSERT [dbo].[Employee] ([EmployeeId], [Name], [RoleId], [Email], [Contact], [DOJ], [DOR], [Status], [Salary])
VALUES (1002, N'Employee 2', 7, N'', N'', CAST(0x8D390B00 AS Date), CAST(0x9A390B00 AS Date), 0, CAST(4000.00 AS Decimal(18, 2)))
You need to use IS NULL operator instead of = NULL in your condition, like this:
SELECT *
FROM Employee
WHERE DOJ <= '2015-02-15'
AND (DOR IS NULL OR DOR > '2015-02-15')
Something like this?
select
EmployeeId,
Name
from
Employee
where
DOJ <= #searchDate and
(DOR is null or DOR > #searchDate)
Try this:
SELECT * FROM Employee
WHERE #dateOfSearch BETWEEN DOJ and COALESCE(DOR, '2099-12-31')
What this query does, is it checks if the search date is between start date and end date. If end date is null then COALESCE function is used to take the very high value date.
Another variation of the previous answers :-)
SELECT * FROM Employee
WHERE #dateOfSearch BETWEEN DOJ and COALESCE(DOR, #dateOfSearch)
Related
I want to calculate SUM of all children with CTE here is DDL/DML. 0 values are which I don't know and to be calculated through aggregation
CREATE TABLE [dbo].[Product]
(
[ID] [INT] IDENTITY(1,1) NOT NULL,
[Hierarchy] [VARCHAR](100) NOT NULL,
[ParentID] [INT] NULL,
[SalesAmount] [INT] NULL
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Product] ON
GO
INSERT [dbo].[Product] ([ID], [Hierarchy], [ParentID], [SalesAmount])
VALUES (1, N'root', NULL, 0),
(2, N'T1', 1, 0),
(3, N'T2', 1, 0),
(4, N'C1', 2, 0),
(5, N'C2', 3, 0),
(6, N'C3', 2, 0),
(7, N'P1', 4, 1000),
(8, N'P2', 5, 2000),
(9, N'P3', 6, 3000)
I tried below query and it gives me following output,
WITH CT AS
(
SELECT
ID, Hierarchy, ParentID, 0 AS Level,
CAST ([Hierarchy] AS VARCHAR (MAX)) AS [Linkeage]
FROM
dbo.Product
WHERE
ParentID IS NULL
UNION ALL
SELECT
pc.ID, pc.Hierarchy, pc.ParentID, p1.Level + 1,
p1.Linkeage + ' -> ' + CAST ([pc].[Hierarchy] AS VARCHAR (MAX))
FROM
dbo.Product AS pc
JOIN
CT AS p1 ON p1.ID = pc.ParentID
),
Aggr AS
(
SELECT
TC.ParentID,
SUM(T.SalesAmount) AS sum_TotalAmt
FROM
CT TC
INNER JOIN
Product AS T ON TC.ID = T.ID
GROUP BY
TC.ParentID
)
SELECT
ID, Hierarchy, T.ParentID, Level, Linkeage, A.sum_TotalAmt
FROM
CT AS T
LEFT JOIN
Aggr AS A ON ISNULL(T.Id, T.ParentID) = A.ParentID
I need existing output + underlined rows as well.
I figured out by my-self by in different approach, i wanted to get aggregates of multiple group by values,
CREATE TABLE [dbo].[Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductType] [varchar](100) NOT NULL,
[ProductCategory] [varchar](100) NOT NULL,
[ProductName] [varchar](100) NOT NULL,
[SalesAmount] [decimal]
) ON [PRIMARY]
So i can simply get output with below
select [ProductType], [ProductCategory], SUM( [SalesAmount] ) as TotalSales
from Product
GROUP BY ROLLUP (ProductType,ProductCategory)
I'm creating a table, which will have a date in one of two columns, or neither.
I'd like the third to auto populate with one of these values, without using an update.
CREATE TABLE [table1]
(
id [BIGINT] NOT NULL,
[date1] [DATETIME] NULL,
[date2] [DATETIME] NULL,
[date] AS (CASE
WHEN [date1] IS NOT NULL THEN [date1]
WHEN [date2] IS NOT NULL THEN [date2]
ELSE NULL
END)
)
This doesn't seem to work when I test using:
INSERT INTO [table1] (id, date1)
VALUES (1, GETDATE())
Can anyone help?
Your code appears to be fine, as seen in this db<>fiddle. However, I would suggest using COALESCE() instead of CASE:
CREATE TABLE [table1] (
id [bigint] NOT NULL,
[date1] [datetime] NULL,
[date2] [datetime] NULL,
[date] AS ( COALESCE(date1, date2) )
);
It is more concise.
I have a SQL query which should convert a datetime. I have tried it in different ways but in every way something goes wrong.
INSERT INTO SETTLEMENT_WIN (COUNTRY,
COMMODITY,
MARKET_PLACE,
START_TIME,
END_TIME)
VALUES ('BE', 'EL', NULL, CONVERT(datetime, '2015-12-14 15:45', 'YYYY-MM-DD HH24:MI'), CONVERT(datetime, '2015-12-14 16:00', 'YYYY-MM-DD HH24:MI'));
gives the error:
Msg 8116, Level 16, State 1, Line 1 Argument data type varchar is
invalid for argument 3 of convert function.
INSERT INTO SETTLEMENT_WIN (COUNTRY,
COMMODITY,
MARKET_PLACE,
START_TIME,
END_TIME)
VALUES ('BE', 'EL', NULL, CONVERT(datetime, '2008-12-14 15:45', 120), CONVERT(datetime, '2015-12-14 16:00', 120));
Inserts the row but in START_TIME and END_TIME there is only the date but not the time
Then I tried to only insert the time but even then only the date was inserted (I am not allowed to change the date format).
Declare #Date1 datetime ='2008-12-14 15:45';
Declare #Date2 datetime ='2015-12-14 16:00';
INSERT INTO SETTLEMENT_WIN (COUNTRY,
COMMODITY,
MARKET_PLACE,
START_TIME,
END_TIME)
VALUES ('BE', 'EL', NULL, CONVERT(datetime, #Date1, 108), CONVERT(datetime, #Date2, 108));
What am I doing wrong? I am using Microsoft SQL Server Management Studio 17.
The CREATE statement for my table is:
CREATE TABLE [SETTLEMENT_WIN] ([SW_ID] [numeric](18, 0) IDENTITY(1, 1) NOT NULL,
[COUNTRY] [varchar](32) NOT NULL,
[COMMODITY] [varchar](32) NOT NULL,
[MARKET_PLACE] [varchar](32),
[START_TIME] [date] NOT NULL,
[END_TIME] [date] NOT NULL,
CONSTRAINT [SW_PK]
PRIMARY KEY ([SW_ID]));
Exactly as I suspected:
[START_TIME] [date] NOT NULL,
[END_TIME] [date] NOT NULL,
If you provide a datetime value to a date datatype the time part of the value will be lost. Try:
DECLARE #d date;
SET #d = '2018-08-02T11:15:59.462'
SELECT #d;
Note it returns 2018-08-02. A date is just that, a date. A datetime, datetime2 or datetimeoffset needs to be used to store a date and time. You'll need to fix your table to resolve this:
ALTER TABLE dbo.SETTLEMENT_WIN ALTER COLUMN [START_TIME] datetime2(0) NOT NULL;
ALTER TABLE dbo.SETTLEMENT_WIN ALTER COLUMN [END_TIME] datetime2(0) NOT NULL;
Then you can insert a date and time value in your table.
#SilverFullbuster, you will need the datatype column in START_TIME and END_TIME changed from date to [datetime].
from:
CREATE TABLE [SETTLEMENT_WIN] ([SW_ID] [numeric](18, 0) IDENTITY(1, 1) NOT NULL,
[COUNTRY] [varchar](32) NOT NULL,
[COMMODITY] [varchar](32) NOT NULL,
[MARKET_PLACE] [varchar](32),
[START_TIME] [date] NOT NULL,
[END_TIME] [date] NOT NULL,
CONSTRAINT [SW_PK]
PRIMARY KEY ([SW_ID]));
to
CREATE TABLE [SETTLEMENT_WIN] ([SW_ID] [numeric](18, 0) IDENTITY(1, 1) NOT NULL,
[COUNTRY] [varchar](32) NOT NULL,
[COMMODITY] [varchar](32) NOT NULL,
[MARKET_PLACE] [varchar](32),
[START_TIME] [datetime] NOT NULL,
[END_TIME] [datetime] NOT NULL,
CONSTRAINT [SW_PK]
PRIMARY KEY ([SW_ID]));
and you can pull the starttime/endtime by extracting from the datetime column like this:
SELECT
SW_ID,
COUNTRY,
COMMODITY,
MARKET_PLACE,
START_TIME=convert(varchar(8), START_TIME, 108),
END_TIME=convert(varchar(8), END_TIME, 108)
FROM
SETTLEMENT_WIN
and results will be like this:
Help would be much appreciated: I want to update values to an audit table (dbo.Audit) prior to updating the same data column.
I have a SELECT statement to retrieve the values (which is created using dynamic SQL) stored in table dbo.[RuleSet], column [SelectStatement].
Issue: I am not sure how to update the Audit table.
CREATE TABLE [dbo].[Audit]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[UpdateID] [int] NULL,
[TableName] [varchar](250) NULL,
[Orig] [varchar](250) NULL
)
CREATE TABLE [dbo].[RuleSet]
(
[UpdateID] [int] IDENTITY(1,1) NOT NULL,
[VID] [int] NULL,
[TableName] [varchar](250) NOT NULL,
[SetColumn] [varchar](250) NOT NULL,
[SetValue] [varchar](250) NOT NULL,
[WhereClause] [varchar](256) NULL,
[SelectStatement] [varchar](4000) NULL
)
INSERT [dbo].[RuleSet] ([UpdateID], [VID], [TableName], [SetColumn], [SetValue], [WhereClause], [SelectStatement])
VALUES (1, 1, N'TableA', N'ColumnA', N'10', N'ColumnA > 10', N'SELECT ColumnA FROM TableA WHERE ColumnA > 10')
INSERT [dbo].[RuleSet] ([UpdateID], [VID], [TableName], [SetColumn], [SetValue], [WhereClause], [SelectStatement])
VALUES (3, 2, N'TableB', N'ColumnB', N'20', N'ColumnB > 20', N'SELECT ColumnB FROM TableB WHERE ColumnB > 20')
GO
The logic of the code I am trying to achieve is:
INSERT INTO [dbo].[Audit]([UpdateID], [TableName], [Orig])
SELECT
[UpdateID], [TableName],
--Value returned from executing the SELECT statement in column[SelectStatement]
FROM
dbo.[RuleSet]
Thank you
You can use EXECUTE sp_executesql to execute [SelectStatement] and store the result in a temp table or a variable. Then use that as a sub query to insert into [dbo].[Audit].
You could make it a lot easier on yourself if you stored your query in [SelectStatement] like this.
N'SELECT ColumnB INTO #TempB FROM TableB WHERE ColumnB > 20'
Then you can just execute it using sp_executesql and select from TempB for the insert.
EXECUTE sp_executesql (SELECT [SelectStatement] FROM [dbo].[RuleSet] where [UpdateID] = ?);
INSERT INTO [dbo].[Audit ] ([UpdateID], [TableName], [Orig])
SELECT [UpdateID], [TableName], #TempB.*
FROM dbo.[RuleSet], #TempB
WHERE [UpdateID] = ?
Note, my example is just a general suggestion and may need tweaking to execute.
I have three tables, table 1, table 2 and table 3. Table 1 records all the existing records, and table 2 records the delta (new updates) to be applied to table 1.
Table 3 is the resultant table.
Table 1 and 3 structure: ID is the primary key
ID, date, location, age, count
Table 2 structure: ID is the primary key
ID, date, location, age, count, ChangeType
Table 2 records new update values only for fields that changed in table 1.
For example:
Table 1
1, 03/03/2017, A, 11, 1
2, 01/03/2017, B, 39, 1
3, 01/01/2017, D, 1, 1
Table 2
2, 03/03/2017,NULL, NULL,2, Update
1, NULL, CC, NULL, NULL, Update
Therefore table 3 should be
1, 03/03/2017, CC, 11, 1
2, 03/03/2017, B, 39, 2
3, 01/01/2017, D, 1, 1
Any suggestions would be appreciated.
GO
/****** Object: Table [dbo].[Table_1] Script Date: 03/03/2017 10:41:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table_1](
[ID] [int] NOT NULL,
[date] [date] NULL,
[location] [nvarchar](50) NULL,
[age] [int] NULL,
[count] [int] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table_2] Script Date: 03/03/2017 10:41:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table_2](
[ID] [int] NOT NULL,
[date] [date] NULL,
[location] [nvarchar](50) NULL,
[age] [int] NULL,
[count] [int] NULL,
[ChangeTyppe] [nvarchar](10) NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table_3] Script Date: 03/03/2017 10:41:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table_3](
[ID] [int] NOT NULL,
[date] [date] NULL,
[location] [nvarchar](50) NULL,
[age] [int] NULL,
[count] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Table_1] ([ID], [date], [location], [age], [count]) VALUES (1, CAST(0x863C0B00 AS Date), N'A', 11, 1)
GO
INSERT [dbo].[Table_1] ([ID], [date], [location], [age], [count]) VALUES (2, CAST(0x843C0B00 AS Date), N'B', 39, 1)
GO
INSERT [dbo].[Table_1] ([ID], [date], [location], [age], [count]) VALUES (3, CAST(0x493C0B00 AS Date), N'D', 1, 1)
GO
INSERT [dbo].[Table_2] ([ID], [date], [location], [age], [count], [ChangeTyppe]) VALUES (2, CAST(0x863C0B00 AS Date), NULL, NULL, 2, N'Update')
GO
INSERT [dbo].[Table_2] ([ID], [date], [location], [age], [count], [ChangeTyppe]) VALUES (1, NULL, N'CC', NULL, NULL, N'Update')
GO
If all you need is a one time thing, then this should work.
Left Join the two tables on the primary key and take the value from T2 if it is not null. Take the value from T1 if the value from 2 was null.
Coalesce will return the first value which is not null.
The values from T2 will be null if the row did not exist in T2 or if the value in T2 was null - per ID.
INSERT dbo.Table_3
( ID, date, location, age, count )
SELECT t1.ID ,
[date] = COALESCE(t2.date, t1.date) ,
[location] = COALESCE(t2.location, t1.location) ,
[age] = COALESCE(t2.age, t1.age) ,
[count] = COALESCE(t2.count, t1.count)
FROM dbo.Table_1 t1
LEFT OUTER JOIN dbo.Table_2 t2 ON t2.ID = t1.ID