Update statement on a cte with subquery - sql

I have a CTE that basically filters data based on certain criteria, the thing is that after filtering I need to update these records to "correct" them but I get a 4104 on the UPDATE statement.
When I call directly the variable I don't have problems but where I do a calculation I get an error because I'm calling the variables from the first and second query.
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY timestmp ASC) order,
*
FROM TSTSOLAP T
(
--SECOND QUERY
SELECT 1 FROM TABLE1 T2
WHERE --CONDITIONS MET
t.user_id = t2.id_user AND
T.ID_TIP = T2.ID_TIP AND
T.ID <> t2.ID AND
(T2.BEG BETWEEN T.BEG AND T.END)
OR T2.BEG = T.END
)
)
UPDATE CTE SET STAT=0, END = (T2.END - 1) --HERE IS WHERE I GET THE: Msg 4104, Level 16, State 1, Line 1
WHERE ORDER> 1
GO
How could I call the non-linked variables?
*Code shortened because lenght

How about just doing a JOIN?
WITH toupdate AS (
SELECT . . . ,
? as order
FROM table1
)
UPDATE T
SET STAT = 0,
END = (T2.END - 1)
FROM T JOIN
table2 T2
ON . . . <conditions here>
WHERE T.ORDER > 1;
Depending on what your conditions are in the subquery, you might still need the EXISTS clause as well.

Related

SQL SP - Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

I am getting an error message when executing this stored procedure, the message is:
Msg 116, Level 16, State 1, Procedure stpr_SP1, Line 42
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 116, Level 16, State 1, Procedure stpr_SP1, Line 55
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Can anyone help with this as I am stuck! Below is the code, thanks.
SELECT CASE #GroupType WHEN 'Store' THEN
(select top 100 percent dbo.Table1.Field1
,dbo.Table1.Location
,count(dbo.Table1.URN) AS [OrderCount]
,convert(numeric(18,2),avg(dbo.Table1.Value)) AS [ValueAvg]
FROM dbo.Table1
GROUP BY dbo.Table1.Field1
,dbo.Table1.Location
ORDER BY dbo.Table1.Field1 ASC
,dbo.Table1.Location ASC)
WHEN 'Customer' THEN
(select top 100 percent dbo.Table1.Field1
,dbo.Table1.InvoiceCode
,dbo.Table1.Location
,count(dbo.Table1.URN) AS [OrderCount]
,convert(numeric(18,2),avg(dbo.Table1.Value)) AS [ValueAvg]
FROM dbo.Table1
GROUP BY dbo.Table1.Field1
,dbo.Table1.InvoiceCode
,dbo.Table1.Location
ORDER BY dbo.Table1.Field1 ASC
,dbo.Table1.InvoiceCode ASC
,dbo.Table1.Location ASC)
END
Presumably you want IF and not SELECT CASE:
IF #GroupType = 'Store'
BEGIN
select top 100 percent dbo.Table1.Field1, . . .
END;
IF #GroupType = 'Customer'
BEGIN
select top 100 percent dbo.Table1.Field1, . . .
END;
A CASE in SQL is an expression, meaning that it returns a value (a single one). What you want is an IF:
IF #GroupType = 'Store'
BEGIN
SELECT t.Field1,
t.Location,
COUNT(t.URN) AS [OrderCount],
CONVERT(numeric(18,2),AVG(t.Value)) AS [ValueAvg]
FROM dbo.Table1 t
GROUP BY t.Field1,
t.Location
ORDER BY t.Field1 ASC,
t.Location ASC
END
IF #GroupType = 'Customer'
BEGIN
SELECT t.Field1,
t.InvoiceCode,
t.Location,
COUNT(t.URN) AS [OrderCount],
CONVERT(numeric(18,2),AVG(t.Value)) AS [ValueAvg]
FROM dbo.Table1 t
GROUP BY t.Field1,
t.InvoiceCode,
t.Location
ORDER BY t.Field1 ASC,
t.InvoiceCode,
t.Location ASC
END

DBO return Only one expression can be specified in the select list

The table [_AUX] receive a value from a asp page (word 'TOJ' was submitted by a form).
Based on this information, I'm trying to create a trigger to update another table called [dbo].[TODOS].
but i have to select only one row randomly that has the 'false' value and then change it to 'true'.
Here's my code:
IF EXISTS (
select top 1 A.flag
from [DBO].[_AUX] AS A
WHERE a.flag = 'TOJ' order by a.ID_AUX desc
)
update DBO.TODOS set DBO.TODOS.[TOJ_FLAG]='true'
where DBO.TODOS.[TOJ_FLAG] =
(
select top 1 t.[toj_flag], t.TODOS
FROM dbo.todos as t
where t.toj_flag = 'false'
ORDER BY NEWID()
)
I'm receiving a error from sql management studio:
Msg 116, Level 16, State 1, Line 14
Only one expression can be specified in the select list when the
subquery is not introduced with EXISTS.
Use in statement like this :
IF EXISTS ( select top 1 A.flag
from [DBO].[_AUX] AS A
WHERE a.flag = 'TOJ' order by a.ID_AUX desc
)
update DBO.TODOS set DBO.TODOS.[TOJ_FLAG]='true'
where DBO.TODOS.[TOJ_FLAG] in
( select t.[toj_flag]
FROM dbo.todos as t
where t.toj_flag = 'false'
ORDER BY NEWID()
)
Update :
update DBO.TODOS set DBO.TODOS.[TOJ_FLAG]='true'
where DBO.TODOS.[TOJ_FLAG] in
( select t.[toj_flag]
FROM dbo.todos as t
where t.toj_flag = 'false'
)

Select 1st and 2nd Record before record X

SQL Server 2008-12
I have table:
InteractionKey char(18)
dEventTime datetime
SeqNo int
cEventData1
There will be multiple entries per InteractionKey - dEventTime only goes out to the Seconds and SeqNo is incremented if two entries occur on the same second.
What I need to do is select the First and Second record BEFORE the record where
cEventData1 = 'Disconnect'
The final product will give me a count of occurrences grouped by cEventData1.
I am currently using a cursor (will update with cursor source momentarily) I would like to use a CTE - but I really struggle with understanding them...
Any ideas would be appreciated!
Update with Data Sample
INTERACTIONKEY dEventTime SeqNo cEventData1
100186322420130722 2013-07-22 11:50:49.000 1 EnterPassword
100186322420130722 2013-07-22 11:50:49.000 2 CheckPassword
100186322420130722 2013-07-22 11:50:49.000 3 Attendant Disconnect
The result of the query would ideally tell me - : NOTE The Action column here can be simply 'Attendant Disconnect' as Action
cEventData1 Action Count
CheckPassword Attendant Disconnect 1
Here is the query I ended up going with based upon the below answer
SELECT DISTINCT t1.InteractionKey,
DisconnectTime = t1.dEventTime,
PreviousEventTime = t2.dEventTime,
PreviousEvent = t2.cEventData1,
t2.SeqNo
FROM IVRHistory t1
OUTER APPLY
( SELECT TOP 1 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM IVRHistory t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime >= t2.dEventTime
AND t1.SeqNo > t2.SeqNo
AND t2.cEventData1 <> 'Attendant Disconnect'
ORDER BY t2.dEventTime DESC, t2.SeqNo DESC
) t2
WHERE t1.cEventData1 = 'Attendant Disconnect'
I would approach this using APPLY:
SELECT t1.InteractionKey,
DisconnectTime = t1.dEventTime,
PreviousEventTime = t2.dEventTime,
PreviousEvent = t2.cEventData1,
t2.SeqNo
FROM T t1
OUTER APPLY
( SELECT TOP 2 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM T t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime > t2.dEventTime
ORDER BY t2.dEventTime DESC
) t2
WHERE t1.cEventData1 = 'Disconnect';
This will give you the two records immediately preceeding the disconnect event. If you need more than two records if there are duplicate times you can use TOP 2 WITH TIES.
Without your sample input and output I am guessing a bit, but from what you have said your final aggregate would be:
SELECT t2.cEventData1,
Occurances = COUNT(*)
FROM T t1
OUTER APPLY
( SELECT TOP 2 t2.dEventTime, t2.SeqNo, t2.cEventData1
FROM T t2
WHERE t1.InteractionKey = t2.InteractionKey
AND t1.dEventTime > t2.dEventTime
ORDER BY t2.dEventTime DESC
) t2
WHERE t1.cEventData1 = 'Disconnect'
GROUP BY t2.cEventData1;

Is syntax like "select field1,field2,field3 from A where (a,b) in (select a,b from B)" supported in derby jdbc?

I once wrote similar queries as below in oracle, and it worked at that time. now I try to do put this in prepareStatement of Derby JDBC.
SELECT THREADID,THREADID2,SIMILARITY FROM S WHERE
(THREADID,THREADID2) IN
(
SELECT T1.ID,T2.ID FROM
(
( SELECT T.ID FROM T WHERE T.POSTTYPEID = '1' ORDER BY ANSWERCOUNT DESC FETCH FIRST 200 ROWS ONLY ) AS T1
JOIN
( SELECT T.ID FROM T WHERE T.POSTTYPEID = '1' ORDER BY ANSWERCOUNT DESC FETCH FIRST 200 ROWS ONLY ) AS T2
)
)
It turned out that I got errors as:
java.sql.SQLSyntaxErrorException: Syntax error:Encountered "," at line 1, column 78
I checked the code, and this error points to the (THREADID,THREADID2) part, is it that this is not supported in JDBC Derby?
no
(THREADID,THREADID2) IN
not working
you must seperate like
WHERE THREADID IN ('your condition') OR THREADID2 IN ('your condition')

Error converting data type varchar to bigint

I have a table with data and one of the columns contains a number stored as text.
When an application updates it, it writes _BAK + datetime stamp behind the number.
I'm now trying to clean up the database by deleting all records that have _BAK in the number column where the most recent one must not be deleted.
id sitenummer
28376 1441_BAK20130213151952032
28377 1441_BAK20130214142314705
In this case the line with ID 28376 is the oldest and must be removed.
I have created a query that should do just that:
;with sel1 AS (
select t1.ID,t1.sitenummer, CONVERT(BIGint,SUBSTRING(t1.sitenummer,CHARINDEX('_',t1.sitenummer,0)+4,50)) as Stamp1
from vdfkraan as t1
where t1.sitenummer like '%_BAK%' and (SELECT COUNT(SUBSTRING(t2.sitenummer,0,CHARINDEX('_',t2.sitenummer,0))) FROM vdfkraan as t2
where SUBSTRING(t1.sitenummer,0,CHARINDEX('_',t1.sitenummer,0))=SUBSTRING(t2.sitenummer,0,CHARINDEX('_',t2.sitenummer,0))) > 1
group by t1.id,t1.sitenummer)
, sel2 AS (
select t3.id, t3.sitenummer, t3.stamp1,
(select TOP(1) t4.stamp1 from sel1 as t4
WHERE SUBSTRING(t4.sitenummer,0,CHARINDEX('_',t4.sitenummer,0)) =SUBSTRING(t3.sitenummer,0,CHARINDEX('_',t3.sitenummer,0))
order by t3.Stamp1 DESC) AS stamp2 from sel1 as t3)
, sel3 AS (select id from sel2 where Stamp1=stamp2)
--delete FROM vdfkraan
--where id IN (SELECT t1.id FROM sel3 as t1)
--select * from sel2
If I uncomment the last line (select * from sel2), it produces the following table:
id sitenummer stamp1 stamp2
28376 1441_BAK20130213151952032 20130213151952032 20130213151952032
28377 1441_BAK20130214142314705 20130214142314705 20130213151952032
Table sel3 contains one record with one column id = 28376.
So that seems to work just as I want it.
Now I comment the select line and uncomment the Delete lines.
Now I get the following error:
Msg 8114, Level 16, State 5, Line 2
Error converting data type varchar to bigint.
So without the delete lines, all is ok, no errors, but with it, I get this error.
I have checked the data, there should not be any problem.
What is going on here?
Try with this:
SELECT v.ID
, v.sitenummer
, ROW_NUMBER() OVER (PARTITION BY LEFT(v.sitenummer, PATINDEX('%_BAK%', v.sitenummer) - 1) ORDER BY v.id DESC) num
INTO #temp
FROM vdfkraan v
WHERE PATINDEX('%_BAK%', v.sitenummer) > 0
DELETE vdfkraan
FROM #temp t
JOIN vdfkraan v ON v.id = t.id
AND t.num <> 1
SELECT *
FROM vdfkraan
Here is an SQL Fiddle
I think you can use grouping instead of window function:
SELECT max(id), max(sitenummer)
FROM vdfkraan
group by left(sitenummer,charindex('_BAK',sitenummer));