I use Clickhouse database.
I have text coming in segments. I need to group all text in one row without duplicate segments
when count(segment) = total Segment.
I create the first table to insert the segments.
then I create a MATERIALIZED view to removing duplicate rows and group all segments.
then move it to the second table but my problem is the view does not show the values.
when I run the query it is working fine
First Table :
CREATE table test_table_1
(
id UInt16,
text String,
totalSegment UInt16,
segmentNumber UInt16,
reference UInt16,
insertTime DateTime
)
ENGINE = ReplacingMergeTree()
order by (id , text , totalSegment , segmentNumber , reference );
Second Table :
CREATE table test_table_2
(
message String,
reference UInt16,
totalSegment UInt16
)
ENGINE = MergeTree()
order by (reference );
MATERIALIZED VIEW :
CREATE MATERIALIZED VIEW consumer To test_table_2
as
SELECT groupArray(text) as message ,reference ,totalSegment
from (
select *
from
(
SELECT COUNT(*) as countSegment, totalSegment, reference
from test_table_1
where (text,totalSegment,reference,insertTime) in (
select text,totalSegment,reference, max(insertTime) as insertTime
from test_table_1
group by text,totalSegment,segmentNumber,reference
)
group by totalSegment, reference
HAVING count(*) = totalSegment
)as a
left join (
select text,segmentNumber,reference, max(insertTime) as insertTime
from test_table_1
group by text,segmentNumber,reference
)as b using (reference)
order by segmentNumber
)
grousp by reference ,totalSegment
order by reference ;
Insert data:
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(1, 'A1 ', 3, 1, '101', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(2, 'B1 ', 2, 1, '202', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(3, 'C2 ', 3, 2, '303', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(4, 'A3 ', 3, 3, '101', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(5, 'A2 ', 3, 2, '101', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(6, 'C1 ', 3, 1, '303', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(7, 'C3 ', 3, 3, '303', now() );
INSERT INTO test_table_1 (id,text, totalSegment, segmentNumber, reference,insertTime) VALUES(8, 'B2 ', 2, 2, '202', now() );
MV is an insert trigger. It NEVER reads the source table -- test_table_1 !!!
https://den-crane.github.io/Everything_you_should_know_about_materialized_views_commented.pdf
https://youtu.be/ckChUkC3Pns?t=9326
Related
My table structure:
declare #TestTable as table
(
id int,
somedate date,
somevalue int
)
insert into #TestTable values
(1, '2019-01-01', 1000),
(2, '2019-01-02', null ),
(3, '2019-01-03', null),
(4, '2019-01-04', null ),
(5, '2019-01-05', 800),
(6, '2019-01-06', null),
(7, '2019-01-07', null),
(8, '2019-01-08', null),
(9, '2019-01-09', null),
(10, '2019-01-10', 700)
Repeat the column value until any change in value of column (somevalue).. Is it possible with window functions?
Required output:
You can achieve that by using window function as well.
try the following:
select id, somevalue, newvalue=max(somevalue) over (partition by c)
from
(
select id, somevalue
,c=count(somevalue) over (order by id)
from #testtable
) t
order by id;
Please find the demo here.
Try this below logic-
DEMO HERE
SELECT A.*,
(
SELECT somevalue
FROM #TestTable
WHERE id = (
SELECT MAX(id)
FROM #TestTable
WHERE id <= A.id
AND somevalue IS NOT NULL
)
) new_column
FROM #TestTable A
ORDER BY A.id
You can achieve this using COALESCE (Transact-SQL)
.
SELECT
[id]
, somedate
, COALESCE(somevalue,
(SELECT TOP (1) somevalue
FROM #TestTable AS p2
WHERE
p2.somevalue IS NOT NULL
AND p2.[id] <= p.[id] ORDER BY p2.[id] DESC))
FROM #TestTable AS p;
Here is the live db<>fiddle demo.
Using code sample below, how can I add missing Param for every EntityId without using WHILE? In the end, I want for every EntityId a row for Param 1, Param 2 and Param 3. I'm using SQL Server 2012.
DECLARE #Data TABLE
(
ID INT IDENTITY(1,1),
EntityId INT,
[Param] VARCHAR(25),
[Value] VARCHAR(25)
)
DECLARE #Param TABLE
(
[Param] VARCHAR(25)
)
INSERT INTO #Param([Param]) VALUES ('Param 1')
INSERT INTO #Param([Param]) VALUES ('Param 2')
INSERT INTO #Param([Param]) VALUES ('Param 3')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(1, 'Param 1', 'Value 1')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(1, 'Param 2', 'Value 2')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(1, 'Param 3', 'Value 3')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(2, 'Param 1', 'Value 1')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(2, 'Param 3', 'Value 3')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(3, 'Param 1', 'Value 1')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(3, 'Param 3', 'Value 3')
INSERT INTO #Data (EntityId, [Param], [Value]) VALUES(4, 'Param 1', 'Value 1')
With a CROSS JOIN of #Param and the distinct EntityIds of #Data and a LEFT JOIN to #Data:
INSERT INTO #Data (EntityId, [Param])
SELECT e.EntityId, p.[Param]
FROM #Param p
CROSS JOIN (SELECT DISTINCT EntityId FROM #Data) AS e
LEFT JOIN #Data d ON d.EntityId = e.EntityId AND d.[Param] = p.[Param]
WHERE d.EntityId IS NULL
See the demo.
I'm not sure if you want the column [Value] to be populated with values just like [Param].
Note my comments.
-- 1. SAMPLE DATA
DECLARE #Data TABLE
(
ID INT IDENTITY(1,1),
EntityId INT,
[Param] VARCHAR(25),
[Value] VARCHAR(25)
);
DECLARE #Param TABLE
(
[Param] VARCHAR(25)
);
INSERT INTO #Param([Param])
VALUES ('Param 1'),('Param 2'),('Param 3')
INSERT INTO #Data (EntityId, [Param], [Value])
VALUES(1, 'Param 1', 'Value 1'),(1, 'Param 2', 'Value 2'),(1, 'Param 3', 'Value 3'),
(2, 'Param 1', 'Value 1'),(2, 'Param 3', 'Value 3'),(3, 'Param 1', 'Value 1'),
(3, 'Param 3', 'Value 3'),(4, 'Param 1', 'Value 1');
-- 2. How to get ALL values
SELECT
dist.EntityId,
p.[Param],
[Value] = REPLACE(p.[Param], 'Param','Value')
FROM
(
SELECT DISTINCT d.EntityId
FROM #data AS d -- OR WHEREEVER I CAN GET A DISTINCT LIST OF EntityIDs
) AS dist(EntityId)
CROSS JOIN #param AS p;
-- 3. How to identify MISSING values
SELECT
dist.EntityId,
[Param] = CAST(p.[Param] AS varchar(25)),
[Value] = CAST(REPLACE(p.[Param], 'Param','Value') AS varchar(25))
FROM
(
SELECT DISTINCT d.EntityId
FROM #data AS d -- OR WHEREEVER I CAN GET A DISTINCT LIST OF EntityIDs
) AS dist(EntityId)
CROSS JOIN #param AS p
EXCEPT
SELECT d.EntityId, d.[param], d.[value]
FROM #data AS d;
-- 4. How to add missing values
INSERT #data
SELECT
dist.EntityId,
[Param] = CAST(p.[Param] AS varchar(25)),
[Value] = CAST(REPLACE(p.[Param], 'Param','Value') AS varchar(25))
FROM
(
SELECT DISTINCT d.EntityId
FROM #data AS d -- OR WHEREEVER I CAN GET A DISTINCT LIST OF EntityIDs
) AS dist(EntityId)
CROSS JOIN #param AS p
EXCEPT
SELECT d.EntityId, d.[param], d.[value]
FROM #data AS d;
If you want to choose the EntityId which records will be inserted so this could be it.
declare #eId int
set #eId = 4
insert into #Data (EntityId, [Param], [Value])
select #eId, [Param], 'Value ' + CAST(RIGHT([Param],1) AS varchar(1))
from #Param
where [Param] NOT IN (select [Param] from #Data where EntityId = #eId)
How can I select only information that start with a #?
I have a table with 5 columns and in one of the columns i.e. the comments column there is information like:
#2345 Changed by Mark
Paul changed ticket number #5923
Someone changed ticket number #5823 and #9333
#3555 is missing from the list, can only see #5789, #9000 and #4568
In the sample of 4 rows above, I want my select statement to return only ticket numbers as shown below:
comments
#2345
#5923
#5823, #9333
#5789, #9000, #4568
Someone said regular expressions can do the work for me but I am fresh graduate and have never seen such before. Can you help me please??
Select the required fields from your database table using SQL, then perform regex operations on the result in another language such as c++, php etc. when outputting your result to the client
First Create Function To extract #numeric values
CREATE FUNCTION dbo.udf_GetNumeric
(
#strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256
)
AS
BEGIN
DECLARE #intAlpha INT
SET #intAlpha = PATINDEX('%[^#0-9]%', #strAlphaNumeric)
BEGIN
WHILE #intAlpha > 0
BEGIN
SET #strAlphaNumeric = STUFF(#strAlphaNumeric, #intAlpha, 1, '' )
SET #intAlpha = PATINDEX('%[^#0-9]%', #strAlphaNumeric )
END
END
RETURN ISNULL(#strAlphaNumeric,0)
END
GO
By Using Below Code we can Extract the numeric values
Declare #TempTable TABLE(ID Int Identity,Value varchar(1000))
INSERT INTO #TempTable
SELECT '#2345 Changed by Mark'
UNION ALL SELECT 'Paul changed ticket number #5923'
UNION ALL SELECT 'Someone changed ticket number #5823 and #9333'
UNION ALL SELECT '#3555 is missing from the list, can only see #5789, #9000 and #4568'
SELECT ID,
RIGHT(LTRIM(REPLACE(Value,'#',' ,#')),LEN(RTRIM(LTRIM(REPLACE(Value,'#',' ,#'))))-1)AS Value FROM
(
SELECT ID,dbo.udf_GetNumeric(Value) AS Value From #TempTable
)Dt
If you need to extract Numeric values Instead of pre-fixed wirh '#' Symbol
SELECT ID,
REPLACE(RIGHT(LTRIM(REPLACE(Value,'#',' ,#')),LEN(RTRIM(LTRIM(REPLACE(Value,'#',' ,#'))))-1),'#',' ')AS Value FROM
(
SELECT ID,dbo.udf_GetNumeric(Value) AS Value From #TempTable
)Dt
OutPut
ID Value
----------
1 #2345
2 #5923
3 #5823 ,#9333
4 #3555 ,#5789 ,#9000 ,#4568
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
Drop table #TempTable
CREATE TABLE [dbo].#TempTable(
[ID] [int] NOT NULL,
[Value] [varchar](1000) NULL
) ON [PRIMARY]
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (1, N'#2345 Changed by Mark #111111,767677,33333,#5656 vbvb')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (2, N'Paul changed ticket number #5923,5555555 464646 #010101,5555544rrr,wwww AND #4 ')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (3, N'Someone changed ticket number #5823 and #9333,7777')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (4, N'#3555 is missing from the list, can only see #5789, #9000 and #4568')
GO
;WITH cte
AS
(
SELECT ID,Split.a.value('.', 'VARCHAR(1000)') AS TablesData
FROM (
SELECT ID,CAST('<S>' + REPLACE(Value, ' ', '</S><S>') + '</S>' AS XML) AS TablesData
FROM #TempTable
) AS A
CROSS APPLY TablesData.nodes('/S') AS Split(a)
)
,Final
AS
(
SELECT ID,TablesData FROM
(
SELECT ID, Split.a.value('.', 'VARCHAR(1000)') AS TablesData,CHARINDEX('#',Split.a.value('.', 'VARCHAR(1000)')) AS Data2
FROM (
SELECT ID,CAST('<S>' + REPLACE(TablesData, ',', '</S><S>') + '</S>' AS XML) AS TablesData
FROM cte
) AS A
CROSS APPLY TablesData.nodes('/S') AS Split(a)
)DT
WHERE dt.Data2 <>0
)
SELECT DISTINCT ID
,STUFF((
SELECT ', ' + CAST(TablesData AS VARCHAR(50))
FROM Final i
WHERE i.ID = o.ID
FOR XML PATH('')
), 1, 1, '') AS ColumnsWith#ValuesOnly
FROM Final o
ORDER BY 1 ASC
OutPut
ID ColumnsWith#ValuesOnly
---------------------------
1 #2345, #111111, #5656
2 #5923, #010101, #4
3 #5823, #9333
4 #3555, #5789, #9000, #4568
The best way is to use this script below:
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
Drop table #TempTable
CREATE TABLE [dbo].#TempTable(
[ID] [int] NOT NULL,
[Value] [varchar](1000) NULL
) ON [PRIMARY]
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (1, N'#2345 Changed by Mark #111111,767677,33333,#5656 vbvb')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (2, N'Paul changed ticket number #5923,5555555 464646 #010101,5555544rrr,wwww AND #4 ')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (3, N'Someone changed ticket number #5823 and #9333,7777')
GO
INSERT [dbo].#TempTable ([ID], [Value]) VALUES (4, N'#3555 is missing from the list, can only see #5789, #9000 and #4568')
GO
;WITH cte
AS
(
SELECT ID,Split.a.value('.', 'VARCHAR(1000)') AS TablesData
FROM (
SELECT ID,CAST('<S>' + REPLACE(Value, ' ', '</S><S>') + '</S>' AS XML) AS TablesData
FROM #TempTable
) AS A
CROSS APPLY TablesData.nodes('/S') AS Split(a)
)
,Final
AS
(
SELECT ID,TablesData FROM
(
SELECT ID, Split.a.value('.', 'VARCHAR(1000)') AS TablesData,CHARINDEX('#',Split.a.value('.', 'VARCHAR(1000)')) AS Data2
FROM (
SELECT ID,CAST('<S>' + REPLACE(TablesData, ',', '</S><S>') + '</S>' AS XML) AS TablesData
FROM cte
) AS A
CROSS APPLY TablesData.nodes('/S') AS Split(a)
)DT
WHERE dt.Data2 <>0
)
SELECT DISTINCT ID
,STUFF((
SELECT ', ' + CAST(TablesData AS VARCHAR(50))
FROM Final i
WHERE i.ID = o.ID
FOR XML PATH('')
), 1, 1, '') AS ColumnsWith#ValuesOnly
FROM Final o
ORDER BY 1 ASC
I'm attempting to have a column return the sum of a weeks worth of hours from a time unit column. However, It's only returning a null value, and I'm not certain why. Could anyone help? Thank you in advance!
SELECT
[Employee Name],
[Week1] = ISNULL(SUM(CASE WHEN tdate BETWEEN DATEADD(Week,-3,Timesheetdate) AND DATEADD(DAY,-1,DATEADD(WEEK,-2,Timesheetdate)) THEN (Units) END),0 )
[Week2] = ISNULL(SUM(CASE WHEN tdate BETWEEN DATEADD(Week,-2,Timesheetdate) AND DATEADD(DAY,-1,DATEADD(WEEK,-1,Timesheetdate)) THEN (Units) END),0 )
From #Temp
LEFT JOIN TransTable ON TranTable.trankey = Timesheet.tkey
Group By
EmployeeName,
tdate,
tunits,
timesheetdate
DROP TABLE #Temp
CREATE TABLE #Temp ( [EmployeeName] varchar(100), Timesheetdate datetime , Units int , tdate datetime)
insert into #Temp values ( 1, '2015-03-02',1,'2015-03-02')
insert into #Temp values ( 1, '2015-02-02',2,'2015-02-02')
insert into #Temp values ( 1, '2015-02-02',3,'2015-02-02')
insert into #Temp values ( 1, '2015-02-27',4,'2015-02-02')
insert into #Temp values ( 1, '2015-03-24',5,'2015-02-02')
insert into #Temp values ( 1, '2015-03-02',1,'2015-02-15')
insert into #Temp values ( 1, '2015-02-02',2,'2015-02-17')
insert into #Temp values ( 1, '2015-02-02',3,'2015-02-18')
insert into #Temp values ( 1, '2015-02-27',4,'2015-02-20')
insert into #Temp values ( 1, '2015-03-24',5,'2015-02-14')
insert into #Temp values ( 1, '2015-03-02',1,'2015-02-28')
insert into #Temp values ( 1, '2015-02-02',2,'2015-02-27')
insert into #Temp values ( 1, '2015-02-02',3,'2015-02-26')
insert into #Temp values ( 1, '2015-02-27',4,'2015-02-25')
insert into #Temp values ( 1, '2015-03-24',5,'2015-02-24')
insert into #Temp values ( 1, '2015-03-02',1,'2015-02-21')
insert into #Temp values ( 1, '2015-02-02',2,'2015-02-20')
insert into #Temp values ( 1, '2015-02-02',3,'2015-02-18')
insert into #Temp values ( 1, '2015-02-27',4,'2015-02-20')
insert into #Temp values ( 1, '2015-03-24',5,'2015-02-18')
SELECT
EmployeeName,
[Week1] = ISNULL(SUM(CASE WHEN tdate BETWEEN DATEADD(Week,-3,Timesheetdate) AND DATEADD(DAY,-1,DATEADD(WEEK,-2,Timesheetdate)) THEN (Units) ELSE 0 END),0 ),
[Week2] = ISNULL(SUM(CASE WHEN tdate BETWEEN DATEADD(Week,-2,Timesheetdate) AND DATEADD(DAY,-1,DATEADD(WEEK,-1,Timesheetdate)) THEN (Units) ELSE 0 END),0 )
From #Temp
GROUP BY EmployeeName
It seems to work just fine, all I did I've added ELSE 0 ( which was not necesary as it works just fine without it too).
Take a better look at your dates. Maybe it should return null
I have 2 table subtopics and userinteractionlog . subtopics have timespent column I want to update timespent column and the value come from userinteractionlog
by using sum(datediff(mi,starttime,endtime)) group by SubTopicid
this is what I have tried but not working...
UPDATE subtopics s
SET timespent =
(
SELECT SUM(DATEDIFF(mi,u.starttime,u.endtime))
FROM Userinteractionlog u
GROUP BY u.subtopicid HAVING s.idsubTopic=u.subtopicid
)
CREATE table Userinteractionlog
(
ID int
, starttime datetime
, endtime datetime
, subtopicid int
)
GO
INSERT INTO Userinteractionlog(ID, starttime, endtime, subtopicid)
VALUES(1, '2014-01-01 00:00:00.000', '2014-03-02 00:00:00.000', 1)
,(2, '2014-05-04 00:00:00.000', '2014-06-06 12:00:00.000', 1)
,(3, '2013-01-01 00:00:00.000', '2013-01-02 00:00:00.000', 2)
CREATE TABLE subtopics
(
timespent bigint
, idsubTopic int
)
GO
INSERT INTO subtopics (timespent, idsubTopic)
VALUES
(NULL, 1)
,(NULL, 2)
GO
UPDATE subtopics
SET timespent =
(
SELECT SUM(DATEDIFF(mi,u.starttime,u.endtime))
FROM Userinteractionlog u
GROUP BY u.subtopicid HAVING idsubTopic=u.subtopicid
)
GO
This returns
timespent idsubTopic
134640 1
1440 2