INSERT INTO #tmp from CTE query - sql

I want to be able to insert the results of this CTE query into a temp table so I can sum the Total column.
CREATE TABLE #tmp
(
SerialNumber NVARCHAR(50),
StartDateTime NVARCHAR(50),
EndDateTime NVARCHAR(50),
Total NVARCHAR(50)
)
;WITH cte1 AS
(
SELECT
*,
CASE
WHEN Temperature > #maxthreshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime) IS NULL THEN 1
WHEN Temperature <= #maxthreshold AND LEAD(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime) > #maxthreshold THEN 1
WHEN Temperature <= #maxthreshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime) > #maxthreshold THEN 1
END AS chg
FROM
[RawData]
WHERE
SerialNumber = #_Serial
AND CombineDateTime BETWEEN #_DateFrom AND #_DateTo
), cte2 AS
(
SELECT
*,
SUM(chg) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime) AS grp
FROM
cte1
)
INSERT INTO #tmp
SELECT
SerialNumber,
MIN(CombineDateTime) AS StartDateTime,
MAX(CombineDateTime) AS EndDateTime,
DATEDIFF(SECOND, MIN(CombineDateTime), MAX(CombineDateTime)) / 60.0 AS 'Total'
FROM
cte2
GROUP BY
SerialNumber, grp
HAVING
MAX(Temperature) > #maxthreshold)
SELECT *
FROM #tmp
DROP TABLE #tmp
I have tried putting the insert in various places, but it does not insert, I have tried the following answers. I am confused as to why the insert won't work as it is outside of the recursion.
Answer 1
Answer 2
TIA

Related

Selection of records on bases of date

Below is my query and I want the selection of Qty from those SKU which is going to expire first. Please help me how can I do this.
DECLARE #Data table (Id int identity(1,1)
, SKU varchar(10)
, QtyRec int
, Expiry date
, Rec date)
DECLARE #Qty int = 20
INSERT #Data VALUES
('001A', 5 ,'2017-01-15','2015-11-14'),
('001A', 8 ,'2017-01-10','2015-11-14'),
('001A', 6 ,'2015-12-15','2015-11-15'),
('001A', 25,'2016-01-01','2015-11-16'),
('001A', 9 ,'2015-12-20','2015-11-17')
;WITH sumqty AS
(
SELECT *, SUM(QtyRec) OVER (PARTITION BY SKU ORDER BY Id) AS TotalQty FROM #Data
)
,takeqty AS (
SELECT *,
CASE
WHEN #Qty >= TotalQty THEN QtyRec
ELSE #Qty - ISNULL(LAG(TotalQty) OVER (PARTITION BY SKU ORDER BY Id), 0)
END AS TakeQty
FROM sumqty
)
SELECT * FROM takeqty WHERE TakeQty > 0
There are many possible outcomes depends on your question:
If you want to order result-set based on Expiry date ascending order, then Use ORDER BY Expiry at the end of CTEs query. Or select top expire: Use SELECT TOP(1) ROW_NUMBER() OVER(ORDER BY Expiry) AS 'SN' instead of SELECT ROW_NUMBER() OVER(ORDER BY Expiry) AS 'SN'
DECLARE #Data table (Id int identity(1,1)
, SKU varchar(10)
, QtyRec int
, Expiry date
, Rec date)
DECLARE #Qty int = 20
INSERT #Data VALUES
('001A', 5 ,'2017-01-15','2015-11-14'),
('001A', 8 ,'2017-01-10','2015-11-14'),
('001A', 6 ,'2015-12-15','2015-11-15'),
('001A', 25,'2016-01-01','2015-11-16'),
('001A', 9 ,'2015-12-20','2015-11-17');
WITH sumqty AS
(
SELECT *, SUM(QtyRec) OVER (PARTITION BY SKU ORDER BY Id) AS TotalQty FROM #Data
)
,takeqty AS (
SELECT *,
CASE
WHEN #Qty >= TotalQty THEN QtyRec
ELSE #Qty - ISNULL(LAG(TotalQty) OVER (PARTITION BY SKU ORDER BY Id), 0)
END AS TakeQty
FROM sumqty
)
SELECT ROW_NUMBER() OVER(ORDER BY Expiry) AS 'SN'
, SKU
, QtyRec
, Expiry
, Rec
, TotalQty
, TakeQty
FROM takeqty WHERE TakeQty > 0
ORDER BY Expiry;

SQl: Update table with last row from a select

I´m struggling with this update...
I would like to update the column result from table #b with the column columna_1 resulting from the last row of the select below. The matching filed is id_car.
So if you run the select below, the last row of columna_1 is 42229.56230859 and the only record of #b would be:
id_car = 1
result = 42229.56230859
can anyone help please? thanks!!!
CREATE TABLE #b(
id_car int,
result money
)
INSERT INTO #b VALUES (1,0)
CREATE TABLE #f(
id_car int,
fecha datetime,
sales money
)
INSERT INTO #f VALUES (1,'2010-10-31',1.10912)
INSERT INTO #f VALUES (1,'2010-11-30',1.77227)
INSERT INTO #f VALUES (1,'2010-12-31',0.66944)
INSERT INTO #f VALUES (1,'2011-01-31',0.34591)
INSERT INTO #f VALUES (1,'2011-02-28',1.73468)
INSERT INTO #f VALUES (1,'2011-03-31',1.50102)
INSERT INTO #f VALUES (1,'2011-04-30',0.87270)
INSERT INTO #f VALUES (1,'2011-05-31',1.51555)
;with ctesource as
(
select
id_car, fecha, sales,
sum( log( 1e0 + sales ) ) over ( partition by id_car order by fecha rows unbounded preceding) as LogAssetValue
from
#f
WHERE id_car= 1 and fecha > '2010-10-30'
)
select convert(varchar, fecha, 104) AS fecha1, fecha,
CAST(SUM(exp(LogAssetValue)-1)*100 AS numeric(20, 8)) as columna_1
from ctesource
GROUP BY fecha
order by fecha;
SqlFiddleDemo
;with
ctesource as (
SELECT
id_car, fecha, sales,
sum( log( 1e0 + sales ) ) over ( partition by id_car order by fecha rows unbounded preceding) as LogAssetValue,
row_number() over (order by fecha) as rn
FROM
f
WHERE id_car= 1
and fecha > '2010-10-30'
)
SELECT convert(varchar, fecha, 104) AS fecha1,
fecha,
rn,
CAST(SUM(exp(LogAssetValue)-1)*100 AS numeric(20, 8)) as columna_1
FROM ctesource
GROUP BY fecha, rn
HAVING rn = (SELECT max(rn) from ctesource)

Selection One Entry Only As Non Zero In SQl Select

I have a scenario where I have to select multiple rows from table, I have multiple rows of one record but with different status,
at times I have two identical rows with identical data for status < for that case I canted to select Non zero for the first occurrence and set 0 for the remaining occurrences.
Below is the Image to show and I have marked strike-out and marked 0 for the remaining occurrence.
And body could suggest better SQL Query:
Here is the Query: I am getting zero value for status 1 for ID =1 but I need to show first as regular and then 0 if that status repeats again.
CREATE TABLE #Temp
(ID INT,
ItemName varchar(10),
Price Money,
[Status] INT,
[Date] Datetime)
INSERT INTO #Temp VALUES(1,'ABC',10,1,'2014-08-27')
INSERT INTO #Temp VALUES(1,'ABC',10,2,'2014-08-27')
INSERT INTO #Temp VALUES(1,'ABC',10,1,'2014-08-28')
INSERT INTO #Temp VALUES(2,'DEF',25,1,'2014-08-26')
INSERT INTO #Temp VALUES(2,'DEF',25,3,'2014-08-27')
INSERT INTO #Temp VALUES(2,'DEF',25,1,'2014-08-28')
INSERT INTO #Temp VALUES(3,'GHI',30,1,'2014-08-27')
SELECT CASE WHEN Temp.Status = 1 THEN
0
ELSE
Temp.Price END AS Price,
* FROM (SELECT * FROM #Temp) Temp
DROP TABLE #Temp
Here is the result:
You might modify your inner select using Row_Number() and set price to Zero for RowNumber > 1.
SELECT CASE WHEN Temp.RowNumber > 1 THEN
0
ELSE
Temp.Price END AS Price,
* FROM (
SELECT *,Row_Number() over (PARTITION by ID,Status ORDER BY ID,Date) AS 'RowNumber'
FROM #Temp
) Temp
Order by ID,Date
You can try this:
;WITH DataSource AS
(
SELECT RANK() OVER (PARTITION BY [ID], [ItemName], [Price], [Status] ORDER BY Date) AS [RankID]
,*
FROM #Temp
)
SELECT [ID]
,[ItemName]
,IIF([RankID] = 1, [Price], 0)
,[Status]
,[Date]
FROM DataSource
ORDER BY [ID]
,[Date]
Here is the output:
please try this below code . it is working for me.
CREATE TABLE #Temp
(ID INT,
ItemName varchar(10),
Price Money,
[Status] INT,
[Date] Datetime)
INSERT INTO #Temp VALUES(1,'ABC',10,1,'2014-08-27')
INSERT INTO #Temp VALUES(1,'ABC',10,2,'2014-08-27')
INSERT INTO #Temp VALUES(1,'ABC',10,1,'2014-08-28')
INSERT INTO #Temp VALUES(2,'DEF',25,1,'2014-08-26')
INSERT INTO #Temp VALUES(2,'DEF',25,3,'2014-08-27')
INSERT INTO #Temp VALUES(2,'DEF',25,1,'2014-08-28')
INSERT INTO #Temp VALUES(3,'GHI',30,1,'2014-08-27')
select *,case when a.rn=1 and status!=2 then price else 0 end as price from
(select *,ROW_NUMBER() over(partition by status,date order by date asc) rn from #Temp) a
order by ItemName asc
You can do this with UNION:
SELECT * FROM #Temp t
WHERE NOT EXISTS
(SELECT * FROM #Temp
WHERE t.id = id and t.status = status and t.date < date)
UNION ALL
SELECT ID, ItemName, 0 as Price, status, date
WHERE EXISTS
(SELECT * FROM #Temp
WHERE t.id = id and t.status = status and t.date < date)
Or subquery:
SELECT CASE
WHEN (SELECT COUNT(*)
FROM #Temp
WHERE t.id = id and t.status = status
and t.date > date) > 1 THEN 0 ELSE price END as NewPrice, t.*
FROM #Temp t
Or possibly RANK() function:
SELECT CASE
WHEN RANK() OVER (PARTITION BY id, status ORDER BY date) > 1
THEN 0 ELSE Price END,
t.*
FROM #Temp t

SQL: Remove duplicates

How do I remove duplicates from a table that is set up in the following way?
unique_ID | worker_ID | date | type_ID
A worker can have multiple type_ID's associated with them and I want to remove any duplicate types. If there is a duplicate, I want to remove the type with the most recent entry.
A textbook candidate for the window function row_number():
;WITH x AS (
SELECT unique_ID
,row_number() OVER (PARTITION BY worker_ID,type_ID ORDER BY date) AS rn
FROM tbl
)
DELETE FROM tbl
FROM x
WHERE tbl.unique_ID = x.unique_ID
AND x.rn > 1
This also takes care of the situation where a set of dupes on (worker_ID,type_ID) shares the same date.
See the simplified demo on data.SE.
Update with simpler version
Turns out, this can be simplified: In SQL Server you can delete from the CTE directly:
;WITH x AS (
SELECT unique_ID
,row_number() OVER (PARTITION BY worker_ID,type_ID ORDER BY date) AS rn
FROM tbl
)
DELETE x
WHERE rn > 1
delete from table t
where exists ( select 1 from table t2
where t2.worker_id = t.worker_id
and t2.type_id = t.type_id
and t2.date < t.date )
HTH
DELETE FROM #t WHERE unique_Id IN
(
SELECT unique_Id FROM
(
SELECT unique_Id
,Type_Id
,ROW_NUMBER() OVER (PARTITION BY worker_Id, type_Id ORDER BY date) AS rn
FROM #t
) Q
WHERE rn > 1
)
And to test...
DECLARE #t TABLE
(
unique_ID INT IDENTITY,
worker_ID INT,
date DATETIME,
type_ID INT
)
INSERT INTO #t VALUES (1, DATEADD(DAY, 1, GETDATE()), 1)
INSERT INTO #t VALUES (1, GETDATE(), 1)
INSERT INTO #t VALUES (2, GETDATE(), 1)
INSERT INTO #t VALUES (1, DATEADD(DAY, 2, GETDATE()), 1)
INSERT INTO #t VALUES (1, DATEADD(DAY, 3, GETDATE()), 2)
SELECT * FROM #t
DELETE FROM #t WHERE unique_Id IN
(
SELECT unique_Id FROM
(
SELECT unique_Id
,Type_Id
,ROW_NUMBER() OVER (PARTITION BY worker_Id, type_Id ORDER BY date) AS rn
FROM #t
) Q
WHERE rn > 1
)
SELECT * FROM #t
you may use this query
delete from worker where unique_id in (
select max(unique_id) from worker group by worker_ID , type_ID having count(type_id)>1)
here i am assuming worker as your table name

transact-sql question

Assume there were 100 records in tableA and tableA contained a column named 'price'.
How do I select the first-n record if where sum of price > a certain amount (e.g. 1000) without using cursor?
thanks
Top N implies some kind of order, which you did not supply, so I assumed any random order.
You can change this on the OVER clause of the ROW_NUMBER().
Try something like
DECLARE #Table TABLE(
Price FLOAT
)
INSERT INTO #Table SELECT 1
INSERT INTO #Table SELECT 11
INSERT INTO #Table SELECT 12
INSERT INTO #Table SELECT 15
INSERT INTO #Table SELECT 10
INSERT INTO #Table SELECT 65
INSERT INTO #Table SELECT 100
DECLARE #TotalPrice FLOAT
SELECT #TotalPrice = 100
;WITH Vals AS (
SELECT *,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RNR
FROM #Table
)
, Totals AS (
SELECT v.RNR,
SUM(vP.Price) TotalPrice
FROM Vals v LEFT JOIN
Vals vP ON v.RNR >= vP.RNR
GROUP BY v.RNR
)
, LimitValue AS (
SELECT TOP 1
RNR
FROM Totals
WHERE TotalPrice >= #TotalPrice
ORDER BY RNR
)
SELECT *
FROM Vals
WHERE RNR <= (
SELECT RNR
FROM LimitValue
)
select price from tableA
where price > 1000
limit n;
n - no. of records you want in result set
--
Cheers