Showing posts with label statement. Show all posts
Showing posts with label statement. Show all posts

Wednesday, March 28, 2012

Help! The IIF Statement in a query...

Part of the where clause in my SQL Statement is conditional. The query clause is as follows:

SELECT...

FROM...

WHERE PROJECT.COMPLETED<>-1 AND IIF(PROJECT.COST > RANGE.MINRANGE AND PROJECT.COST<RANGE.MAXRANGE , PROJECTRANGE.PROJECTRANGEID <>0 ,NULL)

I guess I didn't translate the if satement correctly because I always got errors when I tried to preview my report.

Need help analyzing the if statement for me. Thanks in advance.

What exactly are you trying to do?

Besides, the IIF you have is not syntactically correctn. IIF(<condition>, Expression if the condition is TRUE, Expression if the condition is FALSE). What you have is IIF( <condition>, <Condition>, <Value>) which is incorrect.

|||

Thanks for reply ndinakar. Here is what I am trying to do:

In the if statement, if ProjectCompleted is true(-1 means false), and if project.cost is greater than minimum range and less than max range, then the where clause should be like the following:

WHERE PROJECT.COMPLETED<>-1 ANDRANGE.PROJECTRANGEID <>0

If the Project.Cost is out of the range of minimum and max range (greater than max range or less than minimum range), then the if statement should not return anything, and the where clause will be like this:

WHERE PROJECT.COMPLETED<>-1

|||

I think I understand your question only partially. So what do you mean when you say return nothing if cost is out of the range? Do you still want to see those records or they should not be in the result set? You can probabbly put a filter on the record set accodringly.

|||Not sure if this will help but it looks to me like you are mixing your languages. IIF is for use in expressions in reporting services table cells etc. In SQL you have to use IF with BEGIN and END for your conditional statements. Have a look at this link which I found very usefulhttp://www.databasejournal.com/features/mssql/article.php/3361651sql

Monday, March 12, 2012

HELP! Dynamic binding of schema element names

Hi all,
I'm trying to achieve the following using SQL and SQLServer2000 is the db
I'm using.
Here's a simple select statement
SELECT column1, column2 FROM my_table WHERE some_condition = 1
What I want to be able to do is bind the name my_table to an actual
tablename during runtime, i.e. when the query executes.
The equivalent effect of what I'd like can be represented as below:
SELECT column1, column2 FROM get_my_table_name( ) WHERE some_condition = 1.
Here get_my_table_name( ) is a function that evaluates and returns the table
name. Things don't work this way however.
Is there a way to accomplish this?
Any replies are greatly appreciated.
Thanks in advance,
--Abhi[posted and mailed, please reply in news]
Abhijith Das (adas@.expeditevcs.com) writes:
> I'm trying to achieve the following using SQL and SQLServer2000 is the db
> I'm using.
> Here's a simple select statement
> SELECT column1, column2 FROM my_table WHERE some_condition = 1
> What I want to be able to do is bind the name my_table to an actual
> tablename during runtime, i.e. when the query executes.
> The equivalent effect of what I'd like can be represented as below:
> SELECT column1, column2 FROM get_my_table_name( ) WHERE some_condition => 1.
> Here get_my_table_name( ) is a function that evaluates and returns the
> table name. Things don't work this way however. Is there a way to
> accomplish this?
Yes. But it is unlikely that it is the right thing to do. Since I don't
know your underlying problem, I cannot suggest a solution here and now.
But this article on my web site, both describes on how you can achieve
this - and why you most probably should not do it anyway.
http://www.sommarskog.se/dynamic_sql.html.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinfo/productdoc/2000/books.asp|||Hi ,
No you can't do that that way. You must use dynamic SQL something like this
Declare @.SQL varchar(1000)
set @.SQL = 'SELECT column1, column2 FROM ' + 'my_table' + ' WHERE
some_condition = 1'
exec @.SQL
--
kind regards
Greg O
Need to document your databases. Use the firs and still the best AGS SQL
Scribe
http://www.ag-software.com
"Abhijith Das" <adas@.expeditevcs.com> wrote in message
news:u400jnbqFHA.544@.TK2MSFTNGP11.phx.gbl...
> Hi all,
> I'm trying to achieve the following using SQL and SQLServer2000 is the db
> I'm using.
> Here's a simple select statement
> SELECT column1, column2 FROM my_table WHERE some_condition = 1
> What I want to be able to do is bind the name my_table to an actual
> tablename during runtime, i.e. when the query executes.
> The equivalent effect of what I'd like can be represented as below:
> SELECT column1, column2 FROM get_my_table_name( ) WHERE some_condition => 1.
> Here get_my_table_name( ) is a function that evaluates and returns the
> table name. Things don't work this way however.
> Is there a way to accomplish this?
> Any replies are greatly appreciated.
> Thanks in advance,
> --Abhi
>

Friday, March 9, 2012

HELP! Concatinated Values

Hello everyone,

I would really appreciate if someone could help me out with this one.

I need to execute a select statement which returns more than one row but I need the values from all the rows returned in a single string.

For example

SELECT * FROM USERS would produce

ID NAME
1 Jason
2 Mark
3 Whatever

I need the returned value to be a string with 'Jason,Mark,Whatever' as a returned result.

Any thoughts anyone?

RegardsI would look towards using a cursor in a stored procedure to loop through each row and concatenating the values one by one.

I'm no big fan of serverside cursors, even if they have their time and place too, so depending on the environment and application demands I would look into putting such logic in the middle tier or even client side.

Cheers,
Robert|||Originally posted by Rawbat
I would look towards using a cursor in a stored procedure to loop through each row and concatenating the values one by one.

I'm no big fan of serverside cursors, even if they have their time and place too, so depending on the environment and application demands I would look into putting such logic in the middle tier or even client side.

Cheers,
Robert

declare @.name varchar(40),@.result varchar(500)
declare Cursor1 cursor
for
SELECT * FROM USERS
open Cursor1
fetch from Cursor1 into @.name
Set @.result=@.name
while(@.@.fetch_status=0)
begin
set @.result = ','+@.name
fetch from Cursor1 into @.name
end

Help! Bad insert to a table which I can't delete now.

I made a mistake in my insert statement, the insert to destination table is
the same as the Source from table. Oops! Now I can't truncate, delete this
table at all. Any way to get rid of it and start again?
Thanks, Alpha
insert into
[TisSuite].[dbo].tblSource_info(extTID,RelatedEmployment,RelatedAutoAccident,RelatedOtherAccident,RelatedNotAccident,
ReleasePatientInfo,PlaceOfService,TypeOfService, EMG,COB)
--We default to not releasing patient info
select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS order by
exttidOops, sorry. I was able to delete the table after all.
"Alpha" wrote:
> I made a mistake in my insert statement, the insert to destination table is
> the same as the Source from table. Oops! Now I can't truncate, delete this
> table at all. Any way to get rid of it and start again?
> Thanks, Alpha
> insert into
> [TisSuite].[dbo].tblSource_info(extTID,RelatedEmployment,RelatedAutoAccident,RelatedOtherAccident,RelatedNotAccident,
> ReleasePatientInfo,PlaceOfService,TypeOfService, EMG,COB)
> --We default to not releasing patient info
> select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS order by
> exttid
>

Help! Bad insert to a table which I can't delete now.

I made a mistake in my insert statement, the insert to destination table is
the same as the Source from table. Oops! Now I can't truncate, delete this
table at all. Any way to get rid of it and start again?
Thanks, Alpha
insert into
[TisSuite].[dbo]. tblSource_info(extTID,RelatedEmployment,
RelatedAuto
Accident,RelatedOtherAccident,RelatedNot
Accident,
ReleasePatientInfo,PlaceOfService,TypeOf
Service, EMG,COB)
--We default to not releasing patient info
select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS orde
r by
exttidOops, sorry. I was able to delete the table after all.
"Alpha" wrote:

> I made a mistake in my insert statement, the insert to destination table i
s
> the same as the Source from table. Oops! Now I can't truncate, delete th
is
> table at all. Any way to get rid of it and start again?
> Thanks, Alpha
> insert into
> [TisSuite].[dbo]. tblSource_info(extTID,RelatedEmployment,
RelatedAu
toAccident,RelatedOtherAccident,RelatedN
otAccident,
> ReleasePatientInfo,PlaceOfService,TypeO
fService, EMG,COB)
> --We default to not releasing patient info
> select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS o
rder by
> exttid
>

Help! Bad insert to a table which I can't delete now.

I made a mistake in my insert statement, the insert to destination table is
the same as the Source from table. Oops! Now I can't truncate, delete this
table at all. Any way to get rid of it and start again?
Thanks, Alpha
insert into
[TisSuite].[dbo].tblSource_info(extTID,RelatedEmployment,RelatedAu toAccident,RelatedOtherAccident,RelatedNotAccident ,
ReleasePatientInfo,PlaceOfService,TypeOfService, EMG,COB)
--We default to not releasing patient info
select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS order by
exttid
Oops, sorry. I was able to delete the table after all.
"Alpha" wrote:

> I made a mistake in my insert statement, the insert to destination table is
> the same as the Source from table. Oops! Now I can't truncate, delete this
> table at all. Any way to get rid of it and start again?
> Thanks, Alpha
> insert into
> [TisSuite].[dbo].tblSource_info(extTID,RelatedEmployment,RelatedAu toAccident,RelatedOtherAccident,RelatedNotAccident ,
> ReleasePatientInfo,PlaceOfService,TypeOfService, EMG,COB)
> --We default to not releasing patient info
> select exttid,0,0,0,1,0,1,41,'','' from [TisSuite].[dbo].tblPCS order by
> exttid
>

Wednesday, March 7, 2012

HELP! - SQL Statement does not work!

select d.dname, count(s.staffid) scount
from tstaff s, tdept d
where s.deptid = d.deptid
group by d.dname
having scount > (select avg(count(s.staffid))
from tstaff s
group by s.staffid)
;

can anyone tell me why the above statement does not run. I am getting the following errors:

ERROR at line 5:
ORA-00904: invalid column name

I am trying to get the name of the department and the number of staff who have a higher than average number of staff assigned to that department... any suggestions!?scount is a column alias so you might want to put the actual expression into the HAVING clause

however, there's still a problem

the subquery in the HAVING clause is not scalar, i.e. it can return more than one value

rudy|||Originally posted by r937
scount is a column alias so you might want to put the actual expression into the HAVING clause

however, there's still a problem

the subquery in the HAVING clause is not scalar, i.e. it can return more than one value

rudy

Thanks! I will try that.|||Originally posted by r937
scount is a column alias so you might want to put the actual expression into the HAVING clause

however, there's still a problem

the subquery in the HAVING clause is not scalar, i.e. it can return more than one value

rudy

Hi,

I tried what you suggested but I am still getting problems. Is there an easier way of comparing the number of staff in each department to the overall average across all departments?!

C.|||the error probably wasn't the alias, then -- like i said, your subquery wasn't scalar :)
select d.dname, count(s.staffid) scount
from tstaff s, tdept d
where s.deptid = d.deptid
group by d.dname
having count(s.staffid) >
( select avg(deptcount)
from ( select d.deptid, count(*) as deptcount
from tstaff s, tdept d
where s.deptid = d.deptid
group by d.deptid ) as deptcounts
)
caution: untested|||Originally posted by r937
the error probably wasn't the alias, then -- like i said, your subquery wasn't scalar :)
select d.dname, count(s.staffid) scount
from tstaff s, tdept d
where s.deptid = d.deptid
group by d.dname
having count(s.staffid) >
( select avg(deptcount)
from ( select d.deptid, count(*) as deptcount
from tstaff s, tdept d
where s.deptid = d.deptid
group by d.deptid ) as deptcounts
)
caution: untested

cheers! I will give it a go - thanks a million.

HELP! - 8060 limit/select statement

BTW, I'm using SQL Server 2000
Thanks again...
"segis bata" <segisbata@.hotmail.com> wrote in message
news:%23wY31UQdIHA.4744@.TK2MSFTNGP06.phx.gbl...
> Hello all,
> I want to know if it's possible to make a select statement that brings
> only the records with a number of bytes of less than 8060
> so, imagine I have a table with 10 records, and two of those ten records
> have more than 8060 bytes, so, if I do this:
> select a, b, c, d from tableX
> where (len(a)+len(b)+len(c)+len(d) < 8060)
> it will only bring 8 records, not 10
> I tried this approach and it doesn't work, so, my question is, is there a
> way (similar to this) using a select statement to limit the results to
> those records with less than 8060 bytes, so I will never get the error?
> Thanks again for all your help!,
> SB-R
On Feb 22, 8:43Xam, "segis bata" <segisb...@.hotmail.com> wrote:
> BTW, I'm using SQL Server 2000
> Thanks again...
> "segis bata" <segisb...@.hotmail.com> wrote in message
> news:%23wY31UQdIHA.4744@.TK2MSFTNGP06.phx.gbl...
>
>
>
>
>
> - Show quoted text -
Dear Segis,
It is not possible to trim the record size using a where predicate. If
you are using table which has record length more than 8060 bytes then
it should be having varchar column. If so...on the varchar column use
substring function to trim the data above 8060 bytes. Hope this
suggestion helps.
Regards
Balaji
|||The LEN() function returns the number of characters, not the number of
bytes. DATALENGTH() returns the number of bytes. If you have any
NVARCHAR columns, which use two bytes per character, you need to use
DATALENGTH().
Also note that there is overhead to the row that is not captured with
the expression you have. Part of that is two bytes for each varying
length column.
Roy Harvey
Beacon Falls, CT
On Thu, 21 Feb 2008 22:43:49 -0500, "segis bata"
<segisbata@.hotmail.com> wrote:

>BTW, I'm using SQL Server 2000
>Thanks again...
>
>"segis bata" <segisbata@.hotmail.com> wrote in message
>news:%23wY31UQdIHA.4744@.TK2MSFTNGP06.phx.gbl...
>

Monday, February 27, 2012

Help writing SQL

I want to select records where a column is null, is not null or is equal to a specific number. How do I do this in one sql statement. My application is an asp.net web site with a business logic layer, a data access layer and sql server. Thank you in advance.select *
from tb
where isnull(col,'*')=isnull(@.search,'*')

Help writing an If else statement

Hello I'm a newbie to programming and need help writing an if
statement.

I have a database set up in SQL with the following fields:

Category Questions Answers

I only want one category to appear for all of the questions and
answers submitted for that category. The way I have it set up now all
if a question is submitted for the same category then the category
will list twice and a one question under each other.

How do I write something if I Dim Category

If it's the same category but a different question just list that
question under that category. If it's a new category list that
category and the questions and answers under thatJJ297 (nc297@.yahoo.com) writes:

Quote:

Originally Posted by

Hello I'm a newbie to programming and need help writing an if
statement.
>
I have a database set up in SQL with the following fields:
>
Category Questions Answers
>
I only want one category to appear for all of the questions and
answers submitted for that category. The way I have it set up now all
if a question is submitted for the same category then the category
will list twice and a one question under each other.
>
How do I write something if I Dim Category
>
If it's the same category but a different question just list that
question under that category. If it's a new category list that
category and the questions and answers under that


I am afraid that I can only answer with the standard recommendation that
you post:

o CREATE TABLE statements for your table(s).
o INSERT statement with sample data.
o The desired output given the sample.

This helps to clarify what you are asking (which I currently do not
understand), and also makes it easy to develop a tested solution.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||JJ297 wrote:

Quote:

Originally Posted by

Hello I'm a newbie to programming and need help writing an if
statement.
>
I have a database set up in SQL with the following fields:
>
Category Questions Answers
>
I only want one category to appear for all of the questions and
answers submitted for that category. The way I have it set up now all
if a question is submitted for the same category then the category
will list twice and a one question under each other.
>
How do I write something if I Dim Category
>
If it's the same category but a different question just list that
question under that category. If it's a new category list that
category and the questions and answers under that


This sounds like it should be done in a separate reporting
layer, using Crystal Reports or something similar.|||Why are you formatting data in the back end? The basic principle of a
tiered architecture is that display is done in the front end and never
in the back end. This a more basic programming principle than just
SQL and RDBMS.

Help woth cursor!

Hi,
I have a stored procedure which cycles through a select statement and loads
the results into a cursor. It then sends an email off for each result. I
was wondering if it was possible to group all the results into one email?
My stored procedure is below for reference:-
OPEN surveillance_cursor
FETCH NEXT FROM surveillance_cursor
INTO @.REG_NO, @.URN, @.OFFICER, @.REVIEW_DATE, @.OFFICER_EMAIL
-- Check @.@.FETCH_STATUS to see if there are any more rows to fetch.
WHILE @.@.FETCH_STATUS = 0
IF @.OFFICER_EMAIL IS NOT NULL
BEGIN
select @.recipient = LTRIM(RTRIM(@.OFFICER_EMAIL))
select @.sbj = 'List of Renewal Dates'
select @.msg = 'Reg No:- ' + @.REG_NO + ', ' + 'URN:- ' + @.URN + ', ' +
'Officer:- ' + @.OFFICER + ', ' + 'Review Date:- ' + @.REVIEW_DATE
exec master..xp_sendmail @.recipients= @.recipient, @.subject = @.sbj,
@.message=@.msg
-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM surveillance_cursor
INTO @.REG_NO, @.URN, @.OFFICER, @.REVIEW_DATE, @.OFFICER_EMAIL
END
CLOSE surveillance_cursor
DEALLOCATE surveillance_cursor
GO
Any help on this would be greatly appreciated
Thanks
Damon> I have a stored procedure which cycles through a select statement and
> loads the results into a cursor. It then sends an email off for each
> result. I was wondering if it was possible to group all the results into
> one email?
You'll have to be more specific. Do you mean one e-mail for each unique
@.officer_email, or one e-mail total?|||Create another variable e.g @.allMSG , keep adding the data for every
cursor and then do the "exec sp_sendmail after the cursor has finished.
Jack Vamvas
________________________________________
__________________________
Receive free SQL tips - register at www.ciquery.com/sqlserver.htm
SQL Server Performance Audit - check www.ciquery.com/sqlserver_audit.htm
New article by Jack Vamvas - SQL and Markov Chains -
www.ciquery.com/articles/art_04.asp
"Damon" <nonsense@.nononsense.com> wrote in message
news:2F4Ef.71406$zt1.64049@.newsfe5-gui.ntli.net...
> Hi,
> I have a stored procedure which cycles through a select statement and
loads
> the results into a cursor. It then sends an email off for each result. I
> was wondering if it was possible to group all the results into one email?
> My stored procedure is below for reference:-
> OPEN surveillance_cursor
> FETCH NEXT FROM surveillance_cursor
> INTO @.REG_NO, @.URN, @.OFFICER, @.REVIEW_DATE, @.OFFICER_EMAIL
> -- Check @.@.FETCH_STATUS to see if there are any more rows to fetch.
> WHILE @.@.FETCH_STATUS = 0
> IF @.OFFICER_EMAIL IS NOT NULL
> BEGIN
> select @.recipient = LTRIM(RTRIM(@.OFFICER_EMAIL))
> select @.sbj = 'List of Renewal Dates'
> select @.msg = 'Reg No:- ' + @.REG_NO + ', ' + 'URN:- ' + @.URN + ', ' +
> 'Officer:- ' + @.OFFICER + ', ' + 'Review Date:- ' + @.REVIEW_DATE
> exec master..xp_sendmail @.recipients= @.recipient, @.subject = @.sbj,
> @.message=@.msg
> -- This is executed as long as the previous fetch succeeds.
> FETCH NEXT FROM surveillance_cursor
> INTO @.REG_NO, @.URN, @.OFFICER, @.REVIEW_DATE, @.OFFICER_EMAIL
> END
> CLOSE surveillance_cursor
> DEALLOCATE surveillance_cursor
> GO
>
> Any help on this would be greatly appreciated
> Thanks
>
> Damon
>

Friday, February 24, 2012

Help with writing sql statement

I need some help writing a query. I have a text file that will be imported on a weekly basis, with 1000+ rows and 5 columns. This i need to import into table tblECR which i have added 2 of my own columns.

The problem is the text file will arrive with current data and new data. The current data may or may not have changed (dates, status etc). How do i go about importing the new data and updating the existing data with the new fields, without deleting the data in the 2 columns i've added. I'm using vs 2005 with a sql 2005 express database.

This is the code i'm using to import the data currently. Clicking the button more than once will obviously just import all the data into the database again.

Private Sub CustomerDataToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CustomerDataToolStripMenuItem.Click

'Clear the dataset

dsimport.Clear()

'Set the file variables

Dim strFileName As String

Dim strFilePath As String

Dim sSlash As Single

'Open the file dialog and select the text file to open

Try

With OpenFileDialog1

'Set the initial dialog options

.Title = "Import Customer data file"

.InitialDirectory = "P:\Ian\"

.FileName = ""

.Filter = "File (*.csv)|*.csv|All files (*.*)|*.*"

If OpenFileDialog1.ShowDialog() <> Windows.Forms.DialogResult.Cancel Then

Else

MessageBox.Show("No file was selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information)

Exit Sub

End If

'Strip the filename into its seperate portions

sSlash = InStrRev(.FileName, "\")

strFilePath = Mid(.FileName, 1, CInt(sSlash))

strFileName = Mid(.FileName, CInt(sSlash + 1), Len(.FileName))

End With

'Set the connection properties to read the text file

Dim strConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & strFilePath & ";" & "Extended Properties=""text;HDR=NO;FMT=Delimited"""

Dim conn As New OleDb.OleDbConnection(strConnectionString)

'Open connection with the database.

conn.Open()

'Create new OleDbCommand to return data from the text file

Dim objCmdSelect As New OleDb.OleDbCommand("SELECT * FROM [" & strFileName & "]", conn)

' Create new OleDbDataAdapter that is used to build a DataSet based on the preceding SQL SELECT statement

Dim objAdapter1 As New OleDb.OleDbDataAdapter

'Pass the Select command to the adapter

objAdapter1.SelectCommand = objCmdSelect

'Fill the DataSet with the information from the file

objAdapter1.Fill(dsimport, "Import")

objAdapter1.AcceptChangesDuringFill = False

'Clean up objects

conn.Close()

Catch ex As Exception

MsgBox(ex.Message).ToString()

Exit Sub

End Try

'Now import the data into the table

Dim sqlcn As New SqlConnection(ConnString)

Dim sqlcmd_ECR As New SqlCommand

Dim dr As DataRow

Try

sqlcn.Open()

'Setup the sql command to enter data into the ECR table

sqlcmd_ECR.Connection = sqlcn

sqlcmd_ECR.CommandText = "Insert into tblECR_Test(ECR_No,Aims_No,ECR_Type) Values(@.a,@.b,@.c)"

'Setup the sql parameters to enter data into the ECR table

sqlcmd_ECR.Parameters.Add("@.a", SqlDbType.Int)

sqlcmd_ECR.Parameters.Add("@.b", SqlDbType.Int)

sqlcmd_ECR.Parameters.Add("@.c", SqlDbType.VarChar, 255)

Try

For Each dr In dsimport.Tables(0).Rows

sqlcmd_ECR.Parameters("@.a").Value = dr(0)

sqlcmd_ECR.Parameters("@.b").Value = dr(1)

sqlcmd_ECR.Parameters("@.c").Value = dr(2).ToString()

sqlcmd_ECR.ExecuteNonQuery()

Next

Catch ex1 As SqlException

MsgBox(ex1.Message).ToString()

Exit Sub

End Try

MessageBox.Show("The text file was successfully imported.", "Customer data import", MessageBoxButtons.OK, MessageBoxIcon.Information)

Catch ex3 As Exception

MsgBox(ex3.Message).ToString()

End Try

sqlcn.Close()

End Sub

ExecuteNonQuery returns an integer that tells you how many rows were affected by the query, so you could run an update first (trying to update the record assuming it is already there) and then if the rows affected is 0 instead of 1, run the insert.

Sunday, February 19, 2012

Help with UPDATE statement! TY!

Given the table (mytable)
my_id int (pk)
my_type char(1)
my_version tinyint
my_datetime datetime

Example data
1 a 1 1/1/03
2 b 1 1/2/03
3 c 1 1/3/03
4 d 1 1/4/03
5 e 1 1/5/03
6 a 2 null
7 b 2 1/5/03
8 c 2 null
9 d 2 1/5/03
10 e 2 1/6/03

I want to write an update statement that will set all version 2
datetimes to their version 1 value when the version 2 value is null

After the update the data should look like:
Example data
1 a 1 1/1/03
2 b 1 1/2/03
3 c 1 1/3/03
4 d 1 1/4/03
5 e 1 1/5/03
6 a 2 1/1/03
7 b 2 1/5/03
8 c 2 1/3/03
9 d 2 1/5/03
10 e 2 1/6/03

I've tried:

update my_table
set my_datetime = v1.my_datetime
from
(select *
from my_table
where my_version = 1 and my_datetime is not null) v1,
(select *
from my_table
where my_version = 2 and my_datetime is null) v2
where v1.my_type = v2.my_type

But this just updates all version 2 rows to the lowest date.

What am I doing wrong?

TIACan I assume that there is only one row where my_version=1 for each value of
my_type? If so:

UPDATE MyTable
SET my_datetime =
(SELECT my_datetime
FROM MyTable AS M
WHERE my_version = 1
AND my_type = MyTable.my_type)
WHERE my_datetime IS NULL

--
David Portas
----
Please reply only to the newsgroup
--|||"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote in message news:<mdydnYICIoU7kxGiRVn-sQ@.giganews.com>...
> Can I assume that there is only one row where my_version=1 for each value of
> my_type? If so:
> UPDATE MyTable
> SET my_datetime =
> (SELECT my_datetime
> FROM MyTable AS M
> WHERE my_version = 1
> AND my_type = MyTable.my_type)
> WHERE my_datetime IS NULL

David, yes you can assume that. There are more versions than just 1 &
2 though so I modified your where statement to add:
UPDATE MyTable
SET my_datetime =
(SELECT my_datetime
FROM MyTable AS M
WHERE my_version = 1
AND my_type = MyTable.my_type)
WHERE my_datetime IS NULL and my_version = 2

and it worked like a charm! THX!

Help with update statement

Hi guys,

I have the following sample data:

PaperID StatusID StatusDate StatusKey

0001 4566 2003-09-03 00:00:00.000 D

0001 4222 2003-09-03 00:00:00.000 C

0001 4132 2003-09-01 00:00:00.000 A

0002 4222 1999-04-14 00:00:00.000 C

0002 4132 1999-04-10 00:00:00.000 A

0003 4132 1986-08-03 00:00:00.000 A

0003 4566 1986-07-29 00:00:00.000 D

Now, if in the same paperID, there is a statusKy A and the status date is earlier than the other statusDate, i would like to change the other statusdate to be the same as the status date with the statusKy of 'A'. if there is a statusKy 'A', but the other Statusky contains dates that are earlier than the date in StatusKy 'A', then leave it as what it was.

The result i would want to see :

PaperID StatusID StatusDate StatusKey

0001 4566 2003-09-01 00:00:00.000 D

0001 4222 2003-09-01 00:00:00.000 C

0001 4132 2003-09-01 00:00:00.000 A

0002 4222 1999-04-10 00:00:00.000 C

0002 4132 1999-04-10 00:00:00.000 A

0003 4132 1986-08-03 00:00:00.000 A

0003 4566 1986-07-29 00:00:00.000 D

can you guys help me with this issue? i would appreciate it so much. thanksWink

You ought to be able to put together a pretty good 2-pass solution if you will update based on a derived table of the target. You MIGHT be able to put together a 1-pass solution using TSQL UPDATE extensions IF you need a faster solution.

|||Hi Kent, I am really a beginner in t-sql, would you precise what you mean by putting a 1-pass solution using tsql update extensions? thanks.|||

If you want to just view the data like this, you can do it like this:

Code Snippet

--including scripts like this will get you better responses
drop table test
go
create table Test
(
PaperID char(4),
StatusID char(4),
StatusDate smalldatetime,
StatusKey char(1),
Primary Key (PaperId, StatusId)
)
insert into Test
select '0001','4566','2003-09-03 00:00:00.000','D'
union all
select '0001','4222','2003-09-03 00:00:00.000','C'
union all
select '0001','4132','2003-09-01 00:00:00.000','A'
union all
select '0002','4222','1999-04-14 00:00:00.000','C'
union all
select '0002','4132','1999-04-10 00:00:00.000','A'
union all
select '0003','4132','1986-08-03 00:00:00.000','A'
union all
select '0003','4566','1986-07-29 00:00:00.000','D'
go


select Test.PaperId, Test.StatusId,
case when Astatus.StatusDate < Test.StatusDate
then Astatus.StatusDate
else Test.StatusDate
end as StatusDate,
StatusKey
from Test
join ( select PaperId, StatusId, statusDate
from Test
where StatusKey = 'A') as Astatus
on Test.PaperId = Astatus.PaperId

|||

Thank you so much, i really appreciate your help. you guys are awesome, thanks again.

Jul.

|||

Jul:

Sorry that I was unable to finish my response. I thought I had about 15 minutes that I could get you an answer but I have been really slammed with DB2 work lately. I should be able to finish my answer in the morning. What I mean by a 1-pass solution is that it only has to traverse the data of the table 1 time.

Kent

|||

If you are using SQL Server 2005 then you can use the query below instead which scans the data only once.

Code Snippet

select t.PaperId

, t.StatusId

, case when t.Status_A_Date < t.StatusDate then t.Status_A_Date else t.StatusDate end as StatusDate

, t.StatusKey
from (
select *, min(case StatusKey when 'A' then StatusDate end) over(partition by PaperId) as Status_A_Date
from Test
) as t;

|||NP Kent, thanks again for your contribution!!!! |||

Jul:

Here is an example of a 1-pass update that uses the TSQL extensions:

Code Snippet

create table dbo.mockup
( PaperID varchar(5),
StatusID integer,
StatusDate datetime,
StatusKey char(1),
)
go

create index mockup_UpdExt_Cvr
on dbo.mockup (PaperID, StatusKey, StatusDate)
go

insert into mockup
select '0001', 4566, '2003-09-03 00:00:00.000', 'D' union all
select '0001', 4222, '2003-09-03 00:00:00.000', 'C' union all
select '0001', 4132, '2003-09-01 00:00:00.000', 'A' union all
select '0002', 4222, '1999-04-14 00:00:00.000', 'C' union all
select '0002', 4132, '1999-04-10 00:00:00.000', 'A' union all
select '0003', 4132, '1986-08-03 00:00:00.000', 'A' union all
select '0003', 4566, '1986-07-29 00:00:00.000', 'D'

declare @.nextDate datetime

update mockup
set @.nextDate
= case when a.StatusKey = 'A' then a.statusDate
else @.nextDate
end,
statusDate = @.nextDate
from mockup a (index=mockup_UpdExt_Cvr)

select PaperID,
StatusID,
convert(varchar(10), statusDate, 101) as statusDate,
StatusKey
from mockup

/*
PaperID StatusID statusDate StatusKey
- -- -
0001 4566 09/01/2003 D
0001 4222 09/01/2003 C
0001 4132 09/01/2003 A
0002 4222 04/10/1999 C
0002 4132 04/10/1999 A
0003 4132 08/03/1986 A
0003 4566 08/03/1986 D
*/

Before going farther what I would suggest is that under normal circumstances it is probably better to use either Uma's or Louis' code rather than employ the TSQL update extension -- tend to use the update extensions sparingly.

I especially appreciate Uma's response because I keep forgetting about the use of the OVER( PARTITION BY ... ) clause being availabe with aggregate functions. Please stay after me until I get this right. It seems like OVER(ORDER BY ...) is not available for aggregates but only for the ranking functions; is that correct?

|||

Now, what if i would like to select only those that have statusdates that are later than statusdates with statusky 'A'?

Table1

PaperID StatusID StatusDate StatusKey

0001 4566 2003-09-03 00:00:00.000 D

0001 4222 2003-09-03 00:00:00.000 C

0001 4132 2003-09-01 00:00:00.000 A

0002 4222 1999-04-14 00:00:00.000 C

0002 4132 1999-04-10 00:00:00.000 A

0003 4132 1986-08-03 00:00:00.000 A

0003 4566 1986-07-29 00:00:00.000 D

And i would like to have a result of :

PaperID StatusID StatusDate StatusKey

0001 4566 2003-09-03 00:00:00.000 D

0001 4222 2003-09-03 00:00:00.000 C

0001 4132 2003-09-01 00:00:00.000 A

0002 4222 1999-04-14 00:00:00.000 C

0002 4132 1999-04-10 00:00:00.000 A

I do not want to select 0003 because it has the correct data (statusdate with statusky 'A' is later than the other status dates). additionally, if let say i have a paperID that contains a statusky of 'A' and a statusky of 'D' having the same dates, that would not be selected in the query.

What is the best query to use? thanks.