For better understanding please find the attached image (For detailed information please click here)
Condition:
value_string/Value_Float column field value present i.e Greater than 0, consider as Start_DateTime, next row have same value don’t consider that value just ignore that field. else next row it consists different value consider that one as start_datetime.
If value_string/Value_Float column field value 0,consider as End_Time,In every Group if First Value 0 don’t consider.after the start_Datetime arrived 0 considered as End_dateTime
If the group does not finish with 0(End_dateTime) show the field as 'Null'(Example Group C)
Source Table:
Desired Result
Create Table
CREATE TABLE [dbo].[Activity]
(
[DateTime] [datetime] NULL,
[Group] [nvarchar](255) NULL,
[Value_String] [float] NULL,
[Value_Float] [float] NULL
)
Insert values
Insert INTO [Activity] VALUES ( '2021-06-23 11:32.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 12:13.000','A','1',1)
Insert INTO [Activity] VALUES ( '2021-06-23 17:25.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 07:32.000','A','12',12)
Insert INTO [Activity] VALUES ( '2021-06-24 11:30.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 05:02.000','B','15',15)
Insert INTO [Activity] VALUES ( '2021-06-23 06:20.000','B','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 08:16.000','B','5',5)
Insert INTO [Activity] VALUES ( '2021-06-24 19:12.000','B','5',5)
Insert INTO [Activity] VALUES ( '2021-06-24 23:29.000','B','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 11:42.000','C','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 13:20.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-23 16:15.000','C','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 17:52.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-24 23:12.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-23 11:32.000','D','17',17)
Insert INTO [Activity] VALUES ( '2021-06-23 13:47.000','D','15',15)
Insert INTO [Activity] VALUES ( '2021-06-23 16:48.000','D','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 17:32.000','D','24',24)
Insert INTO [Activity] VALUES ( '2021-06-24 19:32.000','D','0',0)
…
select min([Datetime]) as startdt, max(next0datetime) as enddt, [Group], Value_String, Value_Float
from
(
select *, sum(addme) over(partition by [Group] order by [DateTime]) as grpid
from
(
select *,
min(case when Value_String = '0' then [Datetime] end) over(partition by [Group] order by [DateTime] rows between 1 following and unbounded following)
as next0datetime,
case when Value_String <> lag(Value_String) over(partition by [Group] order by [DateTime]) then 1 else 0 end as addme
from dbo.Activity
) as a
) as g
where Value_String <> '0'
group by [Group], grpid, Value_String, Value_Float
order by [Group], startdt, enddt;
Related
I have some data that looks like:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblMyLog]
(
[Pkid] [bigint] IDENTITY(1,1) NOT NULL,
[JobId] [int] NOT NULL,
[log_recorded] [datetime] NOT NULL,
[status] [nvarchar](max) NULL
)
GO
SET IDENTITY_INSERT [dbo].[tblMyLog] ON
GO
INSERT [dbo].[tblMyLog] ([Pkid], [JobId], [log_recorded], [status])
VALUES (1, 1, CAST(N'2021-06-29T15:35:09.917' AS DateTime), N'Started')
GO
INSERT [dbo].[tblMyLog] ([Pkid], [JobId], [log_recorded], [status])
VALUES (2, 1, CAST(N'2021-06-29T15:36:08.810' AS DateTime), N'Ended')
GO
INSERT [dbo].[tblMyLog] ([Pkid], [JobId], [log_recorded], [status])
VALUES (3, 2, CAST(N'2021-06-29T15:33:41.133' AS DateTime), N'Started')
GO
INSERT [dbo].[tblMyLog] ([Pkid], [JobId], [log_recorded], [status])
VALUES (4, 2, CAST(N'2021-06-29T15:35:09.917' AS DateTime), N'Ended')
GO
I would like to get in a format like so I do some joins to tblMyLog from another table:
JobId StartTime EndTime
------------------------------------------------------
1 2021-06-29 15:35:09.917 2021-06-29 15:36:08.810
2 2021-06-29 15:33:41.133 2021-06-29 15:35:09.917
but I can't figure out the pivot table syntax to do this.
Assuming a JobID can have multiple start/end times, we can use the window function sum() over() to create an ad-hoc group Grp
Example
Select JobID
,StartTime = min( case when status='Started' then log_recorded end)
,EndTime = max( case when status='Ended' then log_recorded end)
From (
Select *
,Grp = sum( case when status='Started' then 1 end) over ( partition by JobID order by log_recorded)
From [tblMyLog]
) A
Group By JobID,Grp
Results
JobID StartTime EndTime
1 2021-06-29 15:35:09.917 2021-06-29 15:36:08.810
2 2021-06-29 15:33:41.133 2021-06-29 15:35:09.917
Transpose rows into columns in SQL Server, I try it using pivot but, expected result is not reached, using pivot getting Max value only
CREATE TABLE [dbo].[test]
(
[patientid] [int] NULL,
[sourcename] [varchar](200) NULL,
[identifier] [varchar](100) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'SIN', N'2663563')
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'SIN', N'2453433')
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'MED', N'534545')
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'MED', N'212334')
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'NXG', N'8678')
INSERT [dbo].[test] ([patientid], [sourcename], [identifier])
VALUES (100, N'NXG', N'2131232334')
Expected output:
You can use conditional aggregation with row_number():
select partitionid,
max(case when sourcename = 'SIN' then identifier end) as sin,
max(case when sourcename = 'MED' then identifier end) as med,
max(case when sourcename = 'NXG' then identifier end) as nxg
from (select t.*,
row_number() over (partition by partitionid, sourcename order by identifier) as seqnum
from t
) t
group by partitionid, seqnum
Use row_number() and conditional aggregation:
select patientid,
max(case when sourcename = 'SIN' then identifier end) as sin,
max(case when sourcename = 'MED' then identifier end) as med,
max(case when sourcename = 'NXG' then identifier end) as nxg
from (
select t.*, row_number() over(partition by sourcename, sourcename order by identifier) rn
from test t
) t
group by patientid, rn
i have requirement where i need to show data of both tables when both the ID's are same.when id is present in first table and not there in second table i need to show data from first table
CREATE TABLE [dbo].[TEST](
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Test_History](
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Test_History] Script Date: 06/19/2015 19:01:49 ******/
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'A', CAST(0x0000A4BC01347E88 AS DateTime))
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'I', CAST(0x0000A4BC0134A390 AS DateTime))
INSERT [dbo].[Test_History] ([ID], [Name], [Status], [CreatedDate]) VALUES (2, N'Rohan', N'A', CAST(0x0000A4BC01391FCC AS DateTime))
/****** Object: Table [dbo].[TEST] Script Date: 06/19/2015 19:01:49 ******/
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (2, N'Rohan', N'I', CAST(0x0000A4BC0138D584 AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (1, N'Mohan', N'A', CAST(0x0000A4BC013072DC AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (3, N'Raj', N'A', CAST(0x0000A4BC0138DED7 AS DateTime))
INSERT [dbo].[TEST] ([ID], [Name], [Status], [CreatedDate]) VALUES (4, N'Krishna', N'A', CAST(0x0000A4BC0138EE31 AS DateTime))
so far i have tried my query to achieve the result
select T.ID,COALESCE(T.ID,TT.ID),T.Name,COALESCE(T.Name,TT.Name),T.status,COALESCE(T.status,TT.status)
from Test T LEFT JOIN (Select TOP 1 ID,MIN(Name)name,Status from Test_History
GROUP BY ID,status
)TT
ON T.ID = TT.ID
where T.ID = 3
Id = 1 and 2 present show i will get data from both tables
Id = 3 and 4 not present in the table
so using coalesce i will get the data
from first table and show in 2nd table column also
but is there any other way like both tables are same structure
i'm thinking of
Declare #tablename varchar(10)
IF EXISTS (SELECT 1 from TESt where id = #id)
IF COunt there in both tables
SET #tablename = Test
ELSE
SET #tablename = Test_history
select * from #tablename where id = #ID
can i get any solution like this
You can use EXCEPT.
Here is an example:
SELECT a,b
FROM (
VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10)
) AS MyTable(a, b)
EXCEPT
SELECT a,b
FROM (
VALUES (1, 2), (7, 8), (9, 10)
) AS MyTable(a, b);
This will return all rows of the upper statement, which are not in the second statement.
First: Thanks for the excellent setup for the data related to the question!
If your real question was if table variables can be used as described in your question, the answer is no; or more accurately that its not worth it.
Not recommended:
declare #TableName TABLE (
[ID] [int] NULL,
[Name] [varchar](10) NULL,
[Status] [char](1) NULL,
[CreatedDate] [datetime] NULL)
IF EXISTS (SELECT 1 from TESt where id = #id)
INSERT INTO #TableName SELECT * FROM dbo.TEST WHERE ID = #ID
ELSE INSERT INTO #TableName SELECT * FROM dbo.[Test_History] WHERE ID = #ID
select * from #tablename where id = #ID
Here's the solution I prefer:
DECLARE #ID INT = 3;
SELECT * FROM [dbo].[TEST] ss WHERE ss.id = #id
UNION ALL SELECT * FROM [dbo].[Test_History] th WHERE th.id = #id
and not exists ( SELECT * FROM [dbo].[TEST] ss WHERE ss.id = #id);
UNION ALL performs surprisingly well - don't forget the ALL keyword, and I am assuming that ID is a PK or AK.
If I'm understanding correctly and you want to display all records that match between the two tables and only records from first table when the id does not exist in the second in the same result set, then all you need is a simple left join:
SELECT *
FROM dbo.test t
LEFT OUTER JOIN Test_History th
ON t.id = th.id
WHERE t.id = #id
I am a sql server newbie and trying to select all the customers which have more than 1 orderid. The table looks as follows:
CREATE TABLE [dbo].[orders](
[customerid] [int] NULL,
[orderid] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[orders] ([customerid], [orderid]) VALUES (1, 2)
INSERT [dbo].[orders] ([customerid], [orderid]) VALUES (1, 3)
INSERT [dbo].[orders] ([customerid], [orderid]) VALUES (2, 4)
INSERT [dbo].[orders] ([customerid], [orderid]) VALUES (2, 5)
INSERT [dbo].[orders] ([customerid], [orderid]) VALUES (3, 1)
select customerid
, count(*) as order_count
from orders
group by
customerid
having count(*) > 1
as you'll probably need customer data at some point, you could also try:
select *
from customers
where exists (
select count(*)
from orders
where customers.id = customerid
group by customerid
having count(*) > 1
)
I need your help on making on recursive query using a CTE in SQL Server.
I have order no as input parameter.. I need to display its top parent despatch details. even if I search for its children.. ie if I search for order no 3 I should get its top parent order no. that is 20.
Here is my table structure..
CREATE TABLE #TblSerialNo
(
[SRno] [char](20) NOT NULL ,
[CustSrNo] [varchar](75) NULL
)
CREATE TABLE #TblSerialReleation
(
[SRno] [char](20) NOT NULL ,
[ChildSRno] [char](20) NOT NULL
)
CREATE TABLE #TblDespatch
(
[SRno] [char](20) NOT NULL ,
OrderNo INT NOT NULL
)
INSERT INTO #TblSerialNo VALUES ( 'TS1', 'DD123CV1' )
INSERT INTO #TblSerialNo VALUES ( 'TS2', 'DD123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'TS3', 'DD123CV3' )
INSERT INTO #TblSerialNo VALUES ( 'BS1', 'DD12sfs3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS2', 'DD1et23CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS1', 'DD12e3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'CS2', 'DD12fe3CV2' )
INSERT INTO #TblSerialNo VALUES ( 'BS1aa', 'DD12d3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS1ab', 'DDd123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'BS1ac', 'DD1r23CV3' )
INSERT INTO #TblSerialNo VALUES ( 'BS2aa', 'DDs123CV4' )
INSERT INTO #TblSerialNo VALUES ( 'BS2ab', 'DD12d3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS2ac', 'DD1s23CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS1aa', 'DD1s23CV3' )
INSERT INTO #TblSerialNo VALUES ( 'CS1ab', 'DD12s3CV4' )
INSERT INTO #TblSerialNo VALUES ( 'CS1ac', 'DD123dCV1' )
INSERT INTO #TblSerialNo VALUES ( 'CS2aa', 'DDa123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS2ab', 'DDa123CV3' )
INSERT INTO #TblSerialNo VALUES ( 'CS2ac', 'DDa123CV4' )
--================ Relation table ==============
INSERT INTO #TblSerialReleation VALUES ( 'TS1', 'BS1' )
INSERT INTO #TblSerialReleation VALUES ( 'TS1', 'BS2' )
INSERT INTO #TblSerialReleation VALUES ( 'TS2', 'CS1' )
INSERT INTO #TblSerialReleation VALUES ( 'TS2', 'CS2' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1aa' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1ab' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1ac' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2aa' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2ab' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2ac' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1aa' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1ab' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1ac' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2aa' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2ab' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2ac' )
--=========== Despatch
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ab', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS1aa', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS1ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'TS1', 1 )
INSERT INTO #TblDespatch VALUES ( 'TS3', 2 )
INSERT INTO #TblDespatch VALUES ( 'TS2', 3 )
INSERT INTO #TblDespatch VALUES ( 'BS2ab', 20 )
DROP TABLE #TblDespatch
DROP TABLE #TblSerialNo
DROP TABLE #TblSerialReleation
Thanks in advance.
Looking at your data, the relation seems to go the other way around (BS2ab (Order 20) is the child of TS1(Order 3) through BS2.
If this is the case, starting from the child (BS2ab) you can find its top parent with the following statement:
;with ParentOrders as(
select
convert(char(20), 'BS2ab')as SRno,
0 as Level
union all
select r.SRno, o.Level + 1
from ParentOrders o
join TblSerialReleation r
on o.SRNo = r.ChildSRno
)
select top 1 SRNO
from ParentOrders
order by Level desc
Here's a working sample of the query: http://www.sqlfiddle.com/#!3/e253e/6