Showing posts with label following. Show all posts
Showing posts with label following. Show all posts

Friday, March 30, 2012

Order converted dates in union query

I have the following as part of a union query:

CONVERT(CHAR(8), r.RRDate, 1) AS [Date]

I also want to order by date but when I do that it doesn't order correctly because of the conversion to char data type (for example, it puts 6/15/05 before 9/22/04 because it only looks at the first number(s) and not the year). If I try to cast it back to smalldatetime in the order by clause it tells me that ORDER BY items must appear in the select list if the statement contains a UNION operator. I get the same message if I try putting just "r.RRDate" in the ORDER BY clause. It's not that big of a deal - I can lose the formatting on the date if I need to to get it to sort correctly, but this query gets used frequently and I'd like to keep the formatting if possible.

Thanks,

Dave

Do you really require UNION operator? If the results of each SELECT statement in the UNION is distinct then use UNION ALL. This will also provide better performance since it doesn't do the duplicate elimination step. And if you use UNION ALL then you can use the column name "r.RRDate" in the ORDER BY clause. If you need to use UNION then only way is to specify the column in the SELECT list also if you want it in the ORDER BY clause. Lastly, is there any reason for your to format the date in the query itself. It is usually unnecessary work to do this on the server-side. It is best to send the date value as is and format on the client. Alternatively, you can use a style which is universal and will preserve sorting for example like the ISO unseparated date format (style 112: YYYYMMDD) or ISO 8601 datetime format (style 126: YYYY-MM-DDThh:mm:ss.nnn). Using language dependent style format is always confusing and can cause errors when you try to use it as is in a different system that has a different language setting for example.

ORDER BY with alias

Hi NG,
in my following query I get the error "Invalid column name 'price'" but
everything seems ok:
SELECT row_number() over (order by price) as row_num,
dbo.getProductPrice('1234') as price
MS describes the use of aliases in ORDER BY
http://msdn2.microsoft.com/ms188385.aspx
Any ideas?
Thanks
Andre ScheiberleAndre Scheiberle wrote:
> Hi NG,
> in my following query I get the error "Invalid column name 'price'" but
> everything seems ok:
> SELECT row_number() over (order by price) as row_num,
> dbo.getProductPrice('1234') as price
> MS describes the use of aliases in ORDER BY
> http://msdn2.microsoft.com/ms188385.aspx
> Any ideas?
> Thanks
> Andre Scheiberle
ORDER BY in a query is different to ORDER BY in a ranking function. In
the latter case you can only reference base columns, not aliases. Try
the following (I assume you omitted the FROM clause in error).
SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num, price
FROM
(SELECT dbo.getProductPrice('1234')
FROM tbl) AS T(price) ;
David Portas, SQL Server MVP
Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.
SQL Server Books Online:
http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
--|||does dbo.getProductPrice('1234')
return a table or a scalar value?
--
"Andre Scheiberle" wrote:

> Hi NG,
> in my following query I get the error "Invalid column name 'price'" but
> everything seems ok:
> SELECT row_number() over (order by price) as row_num,
> dbo.getProductPrice('1234') as price
> MS describes the use of aliases in ORDER BY
> http://msdn2.microsoft.com/ms188385.aspx
> Any ideas?
> Thanks
> Andre Scheiberle
>|||ok, in this example it works, but in my Application I use this Query:
SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num, price, article
FROM
products,
(SELECT dbo.getProductPrice(products.article)M tbl) AS T(price) ;
Now an error appears "The multi-part identifier "products.article" could not
be bound."
Thanks
Andre
"David Portas" wrote:

> Andre Scheiberle wrote:
> ORDER BY in a query is different to ORDER BY in a ranking function. In
> the latter case you can only reference base columns, not aliases. Try
> the following (I assume you omitted the FROM clause in error).
> SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num, price
> FROM
> (SELECT dbo.getProductPrice('1234')
> FROM tbl) AS T(price) ;
> --
> David Portas, SQL Server MVP
> Whenever possible please post enough code to reproduce your problem.
> Including CREATE TABLE and INSERT statements usually helps.
> State what version of SQL Server you are using and specify the content
> of any error messages.
> SQL Server Books Online:
> http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
> --
>|||The table return a scalar value
"Omnibuzz" wrote:
> does dbo.getProductPrice('1234')
> return a table or a scalar value?
> --
>
>
> "Andre Scheiberle" wrote:
>|||try this then.
SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num, price, article
from
(SELECT dbo.getProductPrice(article), article
FROM
products) AS T(price, article)
"Omnibuzz" wrote:
> does dbo.getProductPrice('1234')
> return a table or a scalar value?
> --
>
>
> "Andre Scheiberle" wrote:
>|||Andre Scheiberle wrote:
> ok, in this example it works, but in my Application I use this Query:
> SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num, price, article
> FROM
> products,
> (SELECT dbo.getProductPrice(products.article)M tbl) AS T(price) ;
> Now an error appears "The multi-part identifier "products.article" could n
ot
> be bound."
> Thanks
> Andre
>
You can't reference a table from the outer query in a derived table
subquery. Try this (assuming your function is scalar):
SELECT ROW_NUMBER() OVER (ORDER BY price) AS row_num,
price, article
FROM
(SELECT dbo.getProductPrice(article), article
FROM products) AS T(price,article) ;
David Portas, SQL Server MVP
Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.
SQL Server Books Online:
http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
--|||Here is how a SELECT works in SQL ... at least in theory. Real
products will optimize things, but the code has to produce the same
results.
a) Start in the FROM clause and build a working table from all of the
joins, unions, intersections, and whatever other table constructors are
there. The <table expression> AS <correlation name> option allows you
give a name to this working table which you then have to use for the
rest of the containing query.
b) Go to the WHERE clause and remove rows that do not pass criteria;
that is, that do not test to TRUE (i.e. reject UNKNOWN and FALSE). The
WHERE clause is applied to the working set in the FROM clause.
c) Go to the optional GROUP BY clause, make groups and reduce each
group to a single row, replacing the original working table with the
new grouped table. The rows of a grouped table must be group
characteristics: (1) a grouping column (2) a statistic about the group
(i.e. aggregate functions) (3) a function or (4) an expression made up
those three items. The original table no longer exists.
d) Go to the optional HAVING clause and apply it against the grouped
working table; if there was no GROUP BY clause, treat the entire table
as one group.
e) Go to the SELECT clause and construct the expressions in the list.
This means that the scalar subqueries, function calls and expressions
in the SELECT are done after all the other clauses are done. The AS
operator can also give names to expressions in the SELECT list. These
new names come into existence all at once, but after the WHERE clause,
GROUP BY clause and HAVING clause have been executed; you cannot use
them in the SELECT list or the WHERE clause for that reason.
If there is a SELECT DISTINCT, then redundant duplicate rows are
removed. For purposes of defining a duplicate row, NULLs are treated
as matching (just like in the GROUP BY).
f) Nested query expressions follow the usual scoping rules you would
expect from a block structured language like C, Pascal, Algol, etc.
Namely, the innermost queries can reference columns and tables in the
queries in which they are contained.
g) The ORDER BY clause is part of a cursor, not a query. The result
set is passed to the cursor, which can only see the names in the SELECT
clause list, and the sorting is done there. The ORDER BY clause cannot
have expression in it, or references to other columns because the
result set has been converted into a sequential file structure and that
is what is being sorted.
As you can see, things happen "all at once" in SQL, not "from left to
right" as they would in a sequential file/procedural language model. In
those languages, these two statements produce different results:
READ (a, b, c) FROM File_X;
READ (c, a, b) FROM File_X;
while these two statements return the same data:
SELECT a, b, c FROM Table_X;
SELECT c, a, b FROM Table_X;
Think about what a mess this statement is in the SQL model.
SELECT f(c2) AS c1, f(c1) AS c2 FROM Foobar;
That is why such nonsense is illegal syntax.

Order By Update Error

Hi Every1,
I'm getting the following error
Server: Msg 1033, Level 15, State 1, Line 13
The ORDER BY clause is invalid in views, inline functions, derived
tables, and subqueries, unless TOP is also specified.
what I'm trying to do is to update a table based on the select criteria
I have. In that I'm using ORDER BY Clause & this is giving me error.
Here is my sql:
SELECT SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID, COUNT(*)
from PS_TEAM_CODE_TBL A, PS_TEAM_MEMBERS B, PS_MEMBER_PERSON C
WHERE A.SUPPORT_TEAM_CD = B.SUPPORT_TEAM_CD
AND A.EFF_STATUS = 'A'
AND A.EFFDT >= (SELECT MAX(AX.EFFDT) FROM PS_TEAM_CODE_TBL AX
WHERE A.SETID = AX.SETID
AND A.SUPPORT_TEAM_CD = AX.SUPPORT_TEAM_CD)
AND B.SUPPORT_TEAM_MBR = C.SUPPORT_TEAM_MBR
GROUP BY SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID
HAVING COUNT(*) > 1
ORDER BY SUBSTRING(A.DESCR,1,10)
Is it possible to fix this error?
Thanks in advance for your help.Tony,
The query you posted is not an UPDATE statement, View or Function.
I don't see any problems with the query you posted. However, it is not
valid as a view definition, because of the ORDER BY clause, missing
column names for the resultset and maybe more.
In what way to you think that the order is important when updating a
table? What is the actual UPDATE statement you are trying to use?
Gert-Jan
Tony Schplik wrote:
> Hi Every1,
> I'm getting the following error
> Server: Msg 1033, Level 15, State 1, Line 13
> The ORDER BY clause is invalid in views, inline functions, derived
> tables, and subqueries, unless TOP is also specified.
> what I'm trying to do is to update a table based on the select criteria
> I have. In that I'm using ORDER BY Clause & this is giving me error.
> Here is my sql:
> SELECT SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID, COUNT(*)
> from PS_TEAM_CODE_TBL A, PS_TEAM_MEMBERS B, PS_MEMBER_PERSON C
> WHERE A.SUPPORT_TEAM_CD = B.SUPPORT_TEAM_CD
> AND A.EFF_STATUS = 'A'
> AND A.EFFDT >= (SELECT MAX(AX.EFFDT) FROM PS_TEAM_CODE_TBL AX
> WHERE A.SETID = AX.SETID
> AND A.SUPPORT_TEAM_CD = AX.SUPPORT_TEAM_CD)
> AND B.SUPPORT_TEAM_MBR = C.SUPPORT_TEAM_MBR
> GROUP BY SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID
> HAVING COUNT(*) > 1
> ORDER BY SUBSTRING(A.DESCR,1,10)
> Is it possible to fix this error?
> Thanks in advance for your help.|||Gert-Jan,
Thanks for your response. Sorry I forgot to put the update statement.
Here it is
UPDATE Name1
SET NAME1 = 'Z' FROM PS_MEMBER_PERSON WHERE NAME1 =(SELECT SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID, COUNT(*)
from PS_TEAM_CODE_TBL A, PS_TEAM_MEMBERS B, PS_MEMBER_PERSON C
WHERE A.SUPPORT_TEAM_CD = B.SUPPORT_TEAM_CD
AND A.EFF_STATUS = 'A'
AND A.EFFDT >= (SELECT MAX(AX.EFFDT) FROM PS_TEAM_CODE_TBL AX
WHERE A.SETID = AX.SETID
AND A.SUPPORT_TEAM_CD = AX.SUPPORT_TEAM_CD)
AND B.SUPPORT_TEAM_MBR = C.SUPPORT_TEAM_MBR
GROUP BY SUBSTRING(A.DESCR,1,10), B.SUPPORT_TEAM_MBR, EMPLID
HAVING COUNT(*) > 1
ORDER BY SUBSTRING(A.DESCR,1,10)
Even if I take out the order by clause in the update, then it will give
me a different error for the subquery
Do you have any suggestions for that ...
Thanks in advance for your help|||Tony,
Have you looked into the syntax of the UPDATE statement in SQL Server Books
Online?
--
Anithsql

Wednesday, March 28, 2012

ORDER BY returns opposite sequence between SQL 2000 and 2005

I have the following query returning results in opposite order between
versions 2000 and 2005:-
SELECT * FROM tblname where form= 'L'
order by acolumn desc
The database has been migrated from 2000 to 2005, so the structure and data
should be identical. Here's the DDL for the table in SQL2000:-
USE [MSD_Contracts]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tblname](
[Form] [varchar](1) NOT NULL,
[acolumn] [varchar](1) NOT NULL,
[FieldNo] [int] NOT NULL,
[dbField] [varchar](30) NOT NULL,
[Validation] [varchar](20) NOT NULL,
[AllowNulls] [varchar](1) NOT NULL,
CONSTRAINT [PK_tblname_1_12] PRIMARY KEY CLUSTERED
(
[FieldNo] ASC,
[Form] ASC,
[acolumn] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON
[PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
Any ideas please?Hi Adrian
The order should be the case assuming that the collations are the same. Do
you have some sample data? http://www.aspfaq.com/etiquette.asp?id=5006
You should change the varchar(1) columns.
John
"Adrian" wrote:
> I have the following query returning results in opposite order between
> versions 2000 and 2005:-
> SELECT * FROM tblname where form= 'L'
> order by acolumn desc
> The database has been migrated from 2000 to 2005, so the structure and data
> should be identical. Here's the DDL for the table in SQL2000:-
> USE [MSD_Contracts]
> GO
> SET ANSI_NULLS ON
> GO
> SET QUOTED_IDENTIFIER ON
> GO
> SET ANSI_PADDING ON
> GO
> CREATE TABLE [dbo].[tblname](
> [Form] [varchar](1) NOT NULL,
> [acolumn] [varchar](1) NOT NULL,
> [FieldNo] [int] NOT NULL,
> [dbField] [varchar](30) NOT NULL,
> [Validation] [varchar](20) NOT NULL,
> [AllowNulls] [varchar](1) NOT NULL,
> CONSTRAINT [PK_tblname_1_12] PRIMARY KEY CLUSTERED
> (
> [FieldNo] ASC,
> [Form] ASC,
> [acolumn] ASC
> )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY => OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON
> [PRIMARY]
> ) ON [PRIMARY]
> GO
> SET ANSI_PADDING OFF
> Any ideas please?|||Collation sequence is the same in both versions -
SQL_Latin1_General_CP1_CI_AS. Here is some sample data:_
Form FrontBack FieldNo dbField Validation
AllowNulls
-- -- -- --
-- --
L F 470 SignaturePresent AlphaNum
N
L F 210 DependentQ Bit
N
L F 200 DependentN Bit
N
L F 190 DependentY Bit
N
L F 180 MarriageCertQ Bit
N
L F 170 MarriageCertN Bit
N
L F 160 MarriageCertY Bit
N
L F 150 ConsentQ Bit
N
L F 140 ConsentN Bit
N
L F 130 ConsentY Bit
N
L F 120 Under18Years Bit
N
L F 110 CAltered Bit
N
L F 100 SignedAndDatedQ Bit
N
L F 90 SignedAndDatedN Bit
N
L F 80 SignedAndDatedY Bit
N
L F 70 NameAndDOBQ Bit
N
L F 60 NameAndDOBN Bit
N
L F 50 NameAndDOBY Bit
N
L F 40 Barcode Num
N
L F 30 FormType1 AlphaNum
N
L F 20 ImageRef1 AlphaNum
N
L F 10 BatchNo Num
N
L B 420 EvidenceSent Bit
N
L B 410 EvidenceToWinz Bit
N
L B 400 ExtraEvidence Bit
N
L B 390 Oaltered Bit
N
L B 380 BankQ Bit
N
L B 370 BankN Bit
N
L B 360 BankY Bit
N
L B 340 IRDQ Bit
N
L B 330 IRDN Bit
N
L B 320 IRDY Bit
N
L B 310 ResidentQ Bit
N
L B 300 ResidentN Bit
N
L B 290 ResidentY Bit
N
L B 280 CitizenQ Bit
N
L B 270 CitizenN Bit
N
L B 260 CitizenY Bit
N
L B 250 Barcode Num
N
L B 240 FormType2 AlphaNum
N
L B 230 ImageRef2 AlphaNum
N
L B 220 BatchNo Num
N
(42 row(s) affected)
"John Bell" wrote:
> Hi Adrian
> The order should be the case assuming that the collations are the same. Do
> you have some sample data? http://www.aspfaq.com/etiquette.asp?id=5006
> You should change the varchar(1) columns.
> John
> "Adrian" wrote:
> > I have the following query returning results in opposite order between
> > versions 2000 and 2005:-
> > SELECT * FROM tblname where form= 'L'
> > order by acolumn desc
> >
> > The database has been migrated from 2000 to 2005, so the structure and data
> > should be identical. Here's the DDL for the table in SQL2000:-
> > USE [MSD_Contracts]
> > GO
> > SET ANSI_NULLS ON
> > GO
> > SET QUOTED_IDENTIFIER ON
> > GO
> > SET ANSI_PADDING ON
> > GO
> > CREATE TABLE [dbo].[tblname](
> > [Form] [varchar](1) NOT NULL,
> > [acolumn] [varchar](1) NOT NULL,
> > [FieldNo] [int] NOT NULL,
> > [dbField] [varchar](30) NOT NULL,
> > [Validation] [varchar](20) NOT NULL,
> > [AllowNulls] [varchar](1) NOT NULL,
> > CONSTRAINT [PK_tblname_1_12] PRIMARY KEY CLUSTERED
> > (
> > [FieldNo] ASC,
> > [Form] ASC,
> > [acolumn] ASC
> > )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY => > OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON
> > [PRIMARY]
> > ) ON [PRIMARY]
> >
> > GO
> > SET ANSI_PADDING OFF
> >
> > Any ideas please?|||Hi Arian
You did not read the link I posted about sample data.
Here is some code that would have been useful:
USE TEMPDB
GO
CREATE TABLE [dbo].[tblname](
[Form] [varchar](1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[FrontBack] [varchar](1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[FieldNo] [int] NOT NULL ,
[dbField] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[Validation] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[AllowNulls] [varchar](1) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_tblname_1_12] PRIMARY KEY CLUSTERED
(
[FieldNo] ASC,
[Form] ASC,
[FrontBack] ASC
)
)
INSERT INTO tblname (Form, FrontBack, FieldNo, dbField, Validation,
AllowNulls)
SELECT 'L','F',470,'SignaturePresent','AlphaNum','N'
UNION ALL SELECT 'L','F',210,'DependentQ','Bit','N'
UNION ALL SELECT 'L','F',200,'DependentN','Bit','N'
UNION ALL SELECT 'L','F',190,'DependentY','Bit','N'
UNION ALL SELECT 'L','F',180,'MarriageCertQ','Bit','N'
UNION ALL SELECT 'L','F',170,'MarriageCertN','Bit','N'
UNION ALL SELECT 'L','F',160,'MarriageCertY','Bit','N'
UNION ALL SELECT 'L','F',150,'ConsentQ','Bit','N'
UNION ALL SELECT 'L','F',140,'ConsentN','Bit','N'
UNION ALL SELECT 'L','F',130,'ConsentY','Bit','N'
UNION ALL SELECT 'L','F',120,'Under18Years','Bit','N'
UNION ALL SELECT 'L','F',110,'CAltered','Bit','N'
UNION ALL SELECT 'L','F',100,'SignedAndDatedQ','Bit','N'
UNION ALL SELECT 'L','F',90,'SignedAndDatedN','Bit','N'
UNION ALL SELECT 'L','F',80,'SignedAndDatedY','Bit','N'
UNION ALL SELECT 'L','F',70,'NameAndDOBQ','Bit','N'
UNION ALL SELECT 'L','F',60,'NameAndDOBN','Bit','N'
UNION ALL SELECT 'L','F',50,'NameAndDOBY','Bit','N'
UNION ALL SELECT 'L','F',40,'Barcode','Num','N'
UNION ALL SELECT 'L','F',30,'FormType1','AlphaNum','N'
UNION ALL SELECT 'L','F',20,'ImageRef1','AlphaNum','N'
UNION ALL SELECT 'L','F',10,'BatchNo','Num','N'
UNION ALL SELECT 'L','B',420,'EvidenceSent','Bit','N'
UNION ALL SELECT 'L','B',410,'EvidenceToWinz','Bit','N'
UNION ALL SELECT 'L','B',400,'ExtraEvidence','Bit','N'
UNION ALL SELECT 'L','B',390,'Oaltered','Bit','N'
UNION ALL SELECT 'L','B',380,'BankQ','Bit','N'
UNION ALL SELECT 'L','B',370,'BankN','Bit','N'
UNION ALL SELECT 'L','B',360,'BankY','Bit','N'
UNION ALL SELECT 'L','B',340,'IRDQ','Bit','N'
UNION ALL SELECT 'L','B',330,'IRDN','Bit','N'
UNION ALL SELECT 'L','B',320,'IRDY','Bit','N'
UNION ALL SELECT 'L','B',310,'ResidentQ','Bit','N'
UNION ALL SELECT 'L','B',300,'ResidentN','Bit','N'
UNION ALL SELECT 'L','B',290,'ResidentY','Bit','N'
UNION ALL SELECT 'L','B',280,'CitizenQ','Bit','N'
UNION ALL SELECT 'L','B',270,'CitizenN','Bit','N'
UNION ALL SELECT 'L','B',260,'CitizenY','Bit','N'
UNION ALL SELECT 'L','B',250,'Barcode','Num','N'
UNION ALL SELECT 'L','B',240,'FormType2','AlphaNum','N'
UNION ALL SELECT 'L','B',230,'ImageRef2','AlphaNum','N'
UNION ALL SELECT 'L','B',220,'BatchNo','Num','N'
SELECT *
FROM tblname
where form= 'L'
order by FrontBack desc
The output I get from SQL 2000 is:
Form FrontBack FieldNo dbField Validation
AllowNulls
-- -- -- --
-- --
L F 10 BatchNo Num
N
L F 20 ImageRef1 AlphaNum
N
L F 30 FormType1 AlphaNum
N
L F 40 Barcode Num
N
L F 50 NameAndDOBY Bit
N
L F 60 NameAndDOBN Bit
N
L F 70 NameAndDOBQ Bit
N
L F 80 SignedAndDatedY Bit
N
L F 90 SignedAndDatedN Bit
N
L F 100 SignedAndDatedQ Bit
N
L F 110 CAltered Bit
N
L F 120 Under18Years Bit
N
L F 130 ConsentY Bit
N
L F 140 ConsentN Bit
N
L F 150 ConsentQ Bit
N
L F 160 MarriageCertY Bit
N
L F 170 MarriageCertN Bit
N
L F 180 MarriageCertQ Bit
N
L F 190 DependentY Bit
N
L F 200 DependentN Bit
N
L F 210 DependentQ Bit
N
L F 470 SignaturePresent AlphaNum
N
L B 220 BatchNo Num
N
L B 230 ImageRef2 AlphaNum
N
L B 240 FormType2 AlphaNum
N
L B 250 Barcode Num
N
L B 260 CitizenY Bit
N
L B 270 CitizenN Bit
N
L B 280 CitizenQ Bit
N
L B 290 ResidentY Bit
N
L B 300 ResidentN Bit
N
L B 310 ResidentQ Bit
N
L B 320 IRDY Bit
N
L B 330 IRDN Bit
N
L B 340 IRDQ Bit
N
L B 360 BankY Bit
N
L B 370 BankN Bit
N
L B 380 BankQ Bit
N
L B 390 Oaltered Bit
N
L B 400 ExtraEvidence Bit
N
L B 410 EvidenceToWinz Bit
N
L B 420 EvidenceSent Bit
N
(42 row(s) affected)
The output I get from SQL 2005 is:
Form FrontBack FieldNo dbField Validation
AllowNulls
-- -- -- --
-- --
L F 10 BatchNo Num
N
L F 20 ImageRef1 AlphaNum
N
L F 30 FormType1 AlphaNum
N
L F 40 Barcode Num
N
L F 50 NameAndDOBY Bit
N
L F 60 NameAndDOBN Bit
N
L F 70 NameAndDOBQ Bit
N
L F 80 SignedAndDatedY Bit
N
L F 90 SignedAndDatedN Bit
N
L F 100 SignedAndDatedQ Bit
N
L F 110 CAltered Bit
N
L F 120 Under18Years Bit
N
L F 130 ConsentY Bit
N
L F 140 ConsentN Bit
N
L F 150 ConsentQ Bit
N
L F 160 MarriageCertY Bit
N
L F 170 MarriageCertN Bit
N
L F 180 MarriageCertQ Bit
N
L F 190 DependentY Bit
N
L F 200 DependentN Bit
N
L F 210 DependentQ Bit
N
L F 470 SignaturePresent AlphaNum
N
L B 220 BatchNo Num
N
L B 230 ImageRef2 AlphaNum
N
L B 240 FormType2 AlphaNum
N
L B 250 Barcode Num
N
L B 260 CitizenY Bit
N
L B 270 CitizenN Bit
N
L B 280 CitizenQ Bit
N
L B 290 ResidentY Bit
N
L B 300 ResidentN Bit
N
L B 310 ResidentQ Bit
N
L B 320 IRDY Bit
N
L B 330 IRDN Bit
N
L B 340 IRDQ Bit
N
L B 360 BankY Bit
N
L B 370 BankN Bit
N
L B 380 BankQ Bit
N
L B 390 Oaltered Bit
N
L B 400 ExtraEvidence Bit
N
L B 410 EvidenceToWinz Bit
N
L B 420 EvidenceSent Bit
N
(42 row(s) affected)
The order by only guarantees that FrontBack will be ordered 'F' then 'B' and
this is the case on both instances. As FieldNo and Form are not in the order
by their order is not guaranteed.
John
"Adrian" wrote:
> Collation sequence is the same in both versions -
> SQL_Latin1_General_CP1_CI_AS. Here is some sample data:_
> Form FrontBack FieldNo dbField Validation
> AllowNulls
> -- -- -- --
> -- --
> L F 470 SignaturePresent AlphaNum
> N
> L F 210 DependentQ Bit
> N
> L F 200 DependentN Bit
> N
> L F 190 DependentY Bit
> N
> L F 180 MarriageCertQ Bit
> N
> L F 170 MarriageCertN Bit
> N
> L F 160 MarriageCertY Bit
> N
> L F 150 ConsentQ Bit
> N
> L F 140 ConsentN Bit
> N
> L F 130 ConsentY Bit
> N
> L F 120 Under18Years Bit
> N
> L F 110 CAltered Bit
> N
> L F 100 SignedAndDatedQ Bit
> N
> L F 90 SignedAndDatedN Bit
> N
> L F 80 SignedAndDatedY Bit
> N
> L F 70 NameAndDOBQ Bit
> N
> L F 60 NameAndDOBN Bit
> N
> L F 50 NameAndDOBY Bit
> N
> L F 40 Barcode Num
> N
> L F 30 FormType1 AlphaNum
> N
> L F 20 ImageRef1 AlphaNum
> N
> L F 10 BatchNo Num
> N
> L B 420 EvidenceSent Bit
> N
> L B 410 EvidenceToWinz Bit
> N
> L B 400 ExtraEvidence Bit
> N
> L B 390 Oaltered Bit
> N
> L B 380 BankQ Bit
> N
> L B 370 BankN Bit
> N
> L B 360 BankY Bit
> N
> L B 340 IRDQ Bit
> N
> L B 330 IRDN Bit
> N
> L B 320 IRDY Bit
> N
> L B 310 ResidentQ Bit
> N
> L B 300 ResidentN Bit
> N
> L B 290 ResidentY Bit
> N
> L B 280 CitizenQ Bit
> N
> L B 270 CitizenN Bit
> N
> L B 260 CitizenY Bit
> N
> L B 250 Barcode Num
> N
> L B 240 FormType2 AlphaNum
> N
> L B 230 ImageRef2 AlphaNum
> N
> L B 220 BatchNo Num
> N
> (42 row(s) affected)
>
> "John Bell" wrote:
> > Hi Adrian
> >
> > The order should be the case assuming that the collations are the same. Do
> > you have some sample data? http://www.aspfaq.com/etiquette.asp?id=5006
> >
> > You should change the varchar(1) columns.
> >
> > John
> >
> > "Adrian" wrote:
> >
> > > I have the following query returning results in opposite order between
> > > versions 2000 and 2005:-
> > > SELECT * FROM tblname where form= 'L'
> > > order by acolumn desc
> > >
> > > The database has been migrated from 2000 to 2005, so the structure and data
> > > should be identical. Here's the DDL for the table in SQL2000:-
> > > USE [MSD_Contracts]
> > > GO
> > > SET ANSI_NULLS ON
> > > GO
> > > SET QUOTED_IDENTIFIER ON
> > > GO
> > > SET ANSI_PADDING ON
> > > GO
> > > CREATE TABLE [dbo].[tblname](
> > > [Form] [varchar](1) NOT NULL,
> > > [acolumn] [varchar](1) NOT NULL,
> > > [FieldNo] [int] NOT NULL,
> > > [dbField] [varchar](30) NOT NULL,
> > > [Validation] [varchar](20) NOT NULL,
> > > [AllowNulls] [varchar](1) NOT NULL,
> > > CONSTRAINT [PK_tblname_1_12] PRIMARY KEY CLUSTERED
> > > (
> > > [FieldNo] ASC,
> > > [Form] ASC,
> > > [acolumn] ASC
> > > )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY => > > OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON
> > > [PRIMARY]
> > > ) ON [PRIMARY]
> > >
> > > GO
> > > SET ANSI_PADDING OFF
> > >
> > > Any ideas please?

order by question

I have the following SQL query

SQL = "SELECT * from nonconformance INNER JOIN nc_status ON nonconformance.status_id = nc_status.status_id INNER JOIN nc_major_category ON nc_major_category.major_category_id = nonconformance.major_category_id INNER JOIN nc_department ON nc_department.department_id = nonconformance.department_id AND car_only = '0'ORDER by nonconformance.nc_date"

The order by statement is set to sort my data in a datagrid by date. The issue I am having is it sorts by the lastest date first and the newest record or date is the last in the grid, so if i have 500 records the newest one is the last. How can I reverse the order by so that the newest date is first.

thanksORDER by nonconformance.nc_date DESC|||works great thanks

Monday, March 26, 2012

Order by Keyword ranking

I have the following query:
SELECT Distinct DatePosted,p.DateUpdated,Applied = Case when Email is NULL
then ' ' else '*' end,p.PositionID,JobTitle,JobDescription =
substring(JobDescription,1,200),Posted =
replace(convert(varchar,p.DatePosted,6), ' ',''),lastUpdated =
replace(convert(varchar,p.DateUpdated,6),' ',''), Company,Location FROM
ftsolutions..position p left outer join applicantPosition a on (a.PositionID
= p.PositionID and Email = 'tscheiderich@.yahoo.com') where p.ClientID = 1234
and Contains(jobDescription,'developer and sales') order by p.DateUpdated
DESC
I want to change the option to order by keyword ranking.
How would I do this?
Do I have to use Containstable to do it or is there a way to do it directly
with this query?
Thanks,
Tom
You have to use ContainsTable - here is my stab at the query - it is hard
for me to write this as I don't really know your schema - post it for a more
complete solution.
SELECT DatePosted,p.DateUpdated,Applied = Case when Email is NULL
then ' ' else '*' end,p.PositionID,JobTitle,JobDescription =
substring(JobDescription,1,200),Posted =
replace(convert(varchar,p.DatePosted,6), ' ',''),lastUpdated =
replace(convert(varchar,p.DateUpdated,6),' ',''), Company,Location FROM
ftsolutions..position p left outer join applicantPosition a on
(a.PositionID
= p.PositionID and Email = 'tscheiderich@.yahoo.com')
join ContainsTable(applicantPosition,jobDescription,'de veloper and sales')
as ft on a.PositionID=ft.[key]
where p.ClientID = 1234
and Contains(jobDescription,'developer and sales') order by ft.[rank] desc,
p.DateUpdated DESC
Hilary Cotter
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
Looking for a FAQ on Indexing Services/SQL FTS
http://www.indexserverfaq.com
"tshad" <tscheiderich@.ftsolutions.com> wrote in message
news:Ouxp8tTOFHA.3512@.TK2MSFTNGP15.phx.gbl...
> I have the following query:
> SELECT Distinct DatePosted,p.DateUpdated,Applied = Case when Email is NULL
> then ' ' else '*' end,p.PositionID,JobTitle,JobDescription =
> substring(JobDescription,1,200),Posted =
> replace(convert(varchar,p.DatePosted,6), ' ',''),lastUpdated =
> replace(convert(varchar,p.DateUpdated,6),' ',''), Company,Location FROM
> ftsolutions..position p left outer join applicantPosition a on
(a.PositionID
> = p.PositionID and Email = 'tscheiderich@.yahoo.com') where p.ClientID =
1234
> and Contains(jobDescription,'developer and sales') order by p.DateUpdated
> DESC
> I want to change the option to order by keyword ranking.
> How would I do this?
> Do I have to use Containstable to do it or is there a way to do it
directly
> with this query?
> Thanks,
> Tom
>
|||"Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
news:eBriEMUOFHA.2468@.tk2msftngp13.phx.gbl...
> You have to use ContainsTable - here is my stab at the query - it is hard
> for me to write this as I don't really know your schema - post it for a
> more
> complete solution.
That was exactly what I was looking for.
I wasn't sure how to use the containstable (a little confusing). I am still
confused as to why I need the same filter (developer and sales) in both the
Containstable and Contains verbs. But that is how I always see it.
Thanks,
Tom
> SELECT DatePosted,p.DateUpdated,Applied = Case when Email is NULL
> then ' ' else '*' end,p.PositionID,JobTitle,JobDescription =
> substring(JobDescription,1,200),Posted =
> replace(convert(varchar,p.DatePosted,6), ' ',''),lastUpdated =
> replace(convert(varchar,p.DateUpdated,6),' ',''), Company,Location FROM
> ftsolutions..position p left outer join applicantPosition a on
> (a.PositionID
> = p.PositionID and Email = 'tscheiderich@.yahoo.com')
> join ContainsTable(applicantPosition,jobDescription,'de veloper and sales')
> as ft on a.PositionID=ft.[key]
> where p.ClientID = 1234
> and Contains(jobDescription,'developer and sales') order by ft.[rank]
> desc,
> p.DateUpdated DESC
>
> --
> Hilary Cotter
> Looking for a SQL Server replication book?
> http://www.nwsu.com/0974973602.html
> Looking for a FAQ on Indexing Services/SQL FTS
> http://www.indexserverfaq.com
> "tshad" <tscheiderich@.ftsolutions.com> wrote in message
> news:Ouxp8tTOFHA.3512@.TK2MSFTNGP15.phx.gbl...
> (a.PositionID
> 1234
> directly
>
|||Ouch I am sorry, you don't need the second contains.
Try this
SELECT DatePosted,p.DateUpdated,Applied = Case when Email is NULL then ' '
else '*' end,p.PositionID,JobTitle,JobDescription =
substring(JobDescription,1,200),Posted =
replace(convert(varchar,p.DatePosted,6), ' ',''),lastUpdated =
replace(convert(varchar,p.DateUpdated,6),' ',''), Company,Location
FROM ftsolutions..position p left outer join applicantPosition a on
(a.PositionID= p.PositionID and Email = 'tscheiderich@.yahoo.com')
join ContainsTable(applicantPosition,jobDescription,'de veloper and sales')
as ft on a.PositionID=ft.[key] where p.ClientID = 1234 order by ft.[rank]
desc, p.DateUpdated DESC
"tshad" <tscheiderich@.ftsolutions.com> wrote in message
news:%23fGemeUOFHA.1040@.TK2MSFTNGP12.phx.gbl...
> "Hilary Cotter" <hilary.cotter@.gmail.com> wrote in message
> news:eBriEMUOFHA.2468@.tk2msftngp13.phx.gbl...
> That was exactly what I was looking for.
> I wasn't sure how to use the containstable (a little confusing). I am
> still confused as to why I need the same filter (developer and sales) in
> both the Containstable and Contains verbs. But that is how I always see
> it.
> Thanks,
> Tom
>
sql

ORDER BY in subquery of a UNION fails ??

Hi all,

I have the following UNION ALL statement that is my attempt to gather data for the past 5 weekdays (adding a "dummy" row for today's data).

I want the final output to end up in descending order, so for today, I would want today first, then Tuesday, then Monday, then Friday, then Thursday (provided there is data for each sequential day - if not, you get the idea, I want to select back to get the latest 5 days, most recent to oldest).

This select fails, because it doesn't like the ORDER BY in the subqueryselect
CASE
WHEN DATENAME(dw, GETDATE()) = 'Monday' THEN
'MON'
WHEN DATENAME(dw, GETDATE()) = 'Tuesday' THEN
'TUES'
WHEN DATENAME(dw, GETDATE()) = 'Wednesday' THEN
'WED'
WHEN DATENAME(dw, GETDATE()) = 'Thursday' THEN
'THUR'
WHEN DATENAME(dw, GETDATE()) = 'Friday' THEN
'FRI'
END AS Dow, 'N/A' AS Freight
UNION ALL
(select top 4
CASE
WHEN DATENAME(dw, [OrderDate]) = 'Monday' THEN
'MON'
WHEN DATENAME(dw, [OrderDate]) = 'Tuesday' THEN
'TUES'
WHEN DATENAME(dw, [OrderDate]) = 'Wednesday' THEN
'WED'
WHEN DATENAME(dw, [OrderDate]) = 'Thursday' THEN
'THUR'
WHEN DATENAME(dw, [OrderDate]) = 'Friday' THEN
'FRI'
END as DOW,
CAST(CONVERT(int, (Freight * 100)) as VARCHAR(10)) as Freight
from Northwind.dbo.orders where employeeid = 9 order by [OrderDate] desc )

I know you can't use an ORDER BY in a subquery, UNLESS the subquery also uses a TOP n (which this one does)...but does anyone know why this isn't liking my code?

I got the select to work the way I want it to by doing the following (really UGLY) code...SELECT U.DOW, U.Freight FROM
((select
GETDATE() as [OrderDate],
CASE
WHEN DATENAME(dw, GETDATE()) = 'Monday' THEN
'MON'
WHEN DATENAME(dw, GETDATE()) = 'Tuesday' THEN
'TUES'
WHEN DATENAME(dw, GETDATE()) = 'Wednesday' THEN
'WED'
WHEN DATENAME(dw, GETDATE()) = 'Thursday' THEN
'THUR'
WHEN DATENAME(dw, GETDATE()) = 'Friday' THEN
'FRI'
END AS Dow, 'N/A' AS Freight )
UNION ALL
(select h.OrderDate as [OrderDate], h.DOW, h.Freight FROM
(select top 4
[OrderDate] as [OrderDate],
CASE
WHEN DATENAME(dw, [OrderDate]) = 'Monday' THEN
'MON'
WHEN DATENAME(dw, [OrderDate]) = 'Tuesday' THEN
'TUES'
WHEN DATENAME(dw, [OrderDate]) = 'Wednesday' THEN
'WED'
WHEN DATENAME(dw, [OrderDate]) = 'Thursday' THEN
'THUR'
WHEN DATENAME(dw, [OrderDate]) = 'Friday' THEN
'FRI'
END as DOW,
CAST(CONVERT(int, (Freight * 100)) as VARCHAR(10)) as Freight
from Northwind.dbo.orders where employeeid = 9 order by [OrderDate] desc ) H)) U
order by OrderDate descbut am still confounded about why my original sub-select is rejected with such impunity.

My confusion seems likely related to understanding the set theory or basic concepts of the building of the select/Union rather than the way I am using the ORDER BY syntax, but I just can't seem to explain it to myself.

Thoughts?
Thanks!EDIT: Oops - retracted.|||dang, and I had my blistering rebuttal all ready ;)|||Damn that sucks. I was about to post that your place holder does not have an orderdate but neither does the one that works. Going to have to look at this when I get home.|||OMG NOOOOOO!!! Not working on SQL at HOME!! I wouldn't want to be responsible for THAT in any way, shape or form!

Home is for Beer, relaxation, Lovin', and...well...pretty much ANYTHING but working on Paul's SQL questions ;)

...and what do you mean by "placeholder", BTW?|||please explain what "isn't liking my code" means

is there an error message?

without it, we're just guessing

there are other ways of getting the last 4 order dates, by the way, but they involve a self-join or yet another subselect|||Server: Msg 156, Level 15, State 1, Line 29
Incorrect syntax near the keyword 'order'.Yeah, This is not probably the way I woulda done it...

Had a peer at work come to me with this, and ask me why the order-by in the sub-query doesn't work. I could not explain it, so I just banged my head against it until I figured out a way. Then posted here my ugly code just to show what worked. And so anyone so motivated could run the select to see what I am after for output.

Of course a coupla decades in software development have taught me that you are indeed right...more'n one way to skin a catfish. I am of course open to other alternatives, though am not sure off the top of my head that a self-join would be any less ugly (especially when this sub-select theoretically SHOULD work). Of course, I am always learning, and not typically arrogant enough to think my way is the only way :) (though mind you , I am in no way adverse to steppin up to arm-wrestle about it being the RIGHT way :D )

If you want to take the time to post other ways or improvements, I am ALWAYS open to such nudges or downright slapdowns - in fact I LOVE 'em.

I always appreciate it when someone sees thier way clear to burn a few brain cells on my behalf.|||let's start by replacing that hideous CASE expression

select upper(left(datename(dw,getdate())
,3+datepart(dw,getdate())%2)) as DOW|||i'm sorry, i just discovered i don't have northwind to play with

i'll see if i can squeeze this in tomorrow at the job|||since she's been gone it's all work,exercise study sleep. occasionally I go out with the boys, but my first instinct was right.

in the first one that does not work there is no order date in the first half of your union and in the second one you alias GETDATE() as your order date. my brain was just too mushy earlier.|||Hmmmm...if I understand you correctly, I think that is my intent (which doesn't mean SQL will let me do what I think I want to *L*)

I am only trying to ORDER BY the second select in the UNION...that is because the table used in the second union has daily data in it since about June of 1963 (aka, many more than the 4 dates I am interested in). So the second part of the union is simply trying to grab the last 4 dates (most recent) which is why I am trying to use the TOP 4...ORDER BY - - to get just the last 4 dates in table).

My intent in the first (non-working) UNION is to put my "hard-coded" row of TODAY's data in, then add to it the latest 4 days from the table in the second select of the UNION.

I also want the whole thing ordered by date, which is missing from the first UNION, but that part shouldn't matter to me, should it? At least relative to the pulling of the 5 rows I want. The second (working, ugly) select DOES have the overall ORDER BY in it, which probably causes some confusion relative to my question.

I am just trying to figure out why the initial (non-working) select complains of a syntax error, when to my way of thinking, I should be able to put an idependent select in the second half of the UNION and apply the ORDER BY only to that sub-select (it would, again, be a seperate issue to order the whole result of the UNION).

In a nutshell, if I run the second select in the first UNION by itself, it works fine. But when I try to run the whole UNION select, it fails with the previously-noted error. Shouldn't my sub-select work within the UNION if I place it inside parenthesis as I have?

Part of the problem may be that I am not doing a good job of explaining specifically what I think should work *LOL* - - or not understanding your explaination of why it WON'T.

As always, thanks for expending brain cell activity on my behalf.|||the whole UNION is one result set and the order by applies to the whole result set.|||here, this works:select *
from (
select top 4
[OrderDate]
, substring('SUN MON TUESWED THURFRI SAT '
, 4*datepart(dw,[OrderDate])-3,4) as DOW
, right(space(10)+CAST(Freight*100 as VARCHAR(10)),10) as Freight
from Northwind.dbo.orders
where employeeid = 9
order by [OrderDate] desc
) as dt
union all
select getdate()
, substring('SUN MON TUESWED THURFRI SAT '
, 4*datepart(dw,getdate())-3,4) as DOW
, ' N/A' AS Freight|||he already had one that works. he was just wondering why the other did not. but yes yours is prettier.|||AH-HAA!!!!!

I KNEW it was a syntax assumption...

FROM BOL:
The ORDER BY clause can include items not appearing in the select list. However, if SELECT DISTINCT is specified, or if the SELECT statement contains a UNION operator, the sort columns must appear in the select list.

MY problem was that I was trying to FORCE the ORDER BY in my sub-query to work like a NON-UNION sub-query, and could not figure out why my sub-query (with order by) would not function as an independent sub-query (as it would in a JOIN, for example).

And you guys, on a different plane *L*, assumed that I was playing by the taken-for-granted UNION rules understanding.

I KNEW it was gonna be something like that.

Sincere thanks for your patience and willingness to work with me on this. When I cannot understand why something doesn't work when I am playing by the rules, it often turns out that I am not playing by the rules ;)

...either that, or God is just toying with me at the time...

In this case it was the former.

Thanks for trying to explain when I refused to listen - y'all are now in the same fine group as my parents, teachers, and...well, pretty much everyone else I know :D|||in the first one that does not work there is no order date in the first half of your union and in the second one you alias GETDATE() as your order date. my brain was just too mushy earlier.

this is what i was saying, right?|||Yeah, that's what I mean though...I was thinking differently, so even though you posted that, I thought "huh? I don't WANT a date in the first part of the UNION", because I didn't need it in the final output.

At that time I didn't yet realize/know that it was REQUIRED to make the UNION work.

Theoretically, I shouldn't NEED it (SQL Server notwithstanding) because the output of various selects in the UNION should (logically, or non-logically ;) ) be independent of each other, right? From a set theory-type perspective, anyway.

My second select (the one that worked) only ACCIDENTALLY unbroke the rules that got me in the first one.

Thanks regardless, Sean...I really shouldn't let anyone know any more about my thought process than I have to ;)

Order by in a INSERT INTO..SELECT

I have the following basic statements being executed:

Create a temp table, #TempPaging

Insert Into #TempPaging (Col1, Col2)
Select Col1, Col2 From SomeOtherTable Order By Col2, Col1

Select * from #TempPaging

I can't provide a reproduceable scenario right now without making this
into a 200K post, so I'm hoping someone will know what the issue is.. I
can't find anything regarding this in BOL.

Basically the order is off a little bit every now and then when there
are large amounts of data, like more than a couple hundred rows. Is
there something I need to do to guarantee the originally selected
order?

This is very important that it be in order from the original select
statement as this is for paging. Adding an order by in the second
select from the temp table will not fix the problem. In this particular
instance that I have reproduced we are using SQL 2005 but have also
seen this on SQL 2000 servers. I had previously asked this question as
I was using a SELECT INTO statement, but now we are manually creating
the temp table (Pain in the ass) and still having the same issue. Best
case scenario is for it to work for a SELECT INTO.

Any ideas?pb648174 wrote:
> I have the following basic statements being executed:
> Create a temp table, #TempPaging
> Insert Into #TempPaging (Col1, Col2)
> Select Col1, Col2 From SomeOtherTable Order By Col2, Col1
> Select * from #TempPaging
> I can't provide a reproduceable scenario right now without making this
> into a 200K post, so I'm hoping someone will know what the issue is.. I
> can't find anything regarding this in BOL.
> Basically the order is off a little bit every now and then when there
> are large amounts of data, like more than a couple hundred rows. Is
> there something I need to do to guarantee the originally selected
> order?
> This is very important that it be in order from the original select
> statement as this is for paging. Adding an order by in the second
> select from the temp table will not fix the problem. In this particular
> instance that I have reproduced we are using SQL 2005 but have also
> seen this on SQL 2000 servers. I had previously asked this question as
> I was using a SELECT INTO statement, but now we are manually creating
> the temp table (Pain in the ass) and still having the same issue. Best
> case scenario is for it to work for a SELECT INTO.
> Any ideas?

Tables are NOT logically ordered under any circumstances. You need to
specify ORDER BY here:

Select * from #TempPaging
ORDER BY ...

That is, when you QUERY the table, not when you INSERT.

See the following article for some reliable paging techniques (one
example uses the same method you have so avoid that one):
http://www.aspfaq.com/show.asp?id=2120

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||pb648174 (google@.webpaul.net) writes:
> I have the following basic statements being executed:
> Create a temp table, #TempPaging
> Insert Into #TempPaging (Col1, Col2)
> Select Col1, Col2 From SomeOtherTable Order By Col2, Col1
> Select * from #TempPaging
> I can't provide a reproduceable scenario right now without making this
> into a 200K post, so I'm hoping someone will know what the issue is.. I
> can't find anything regarding this in BOL.
> Basically the order is off a little bit every now and then when there
> are large amounts of data, like more than a couple hundred rows. Is
> there something I need to do to guarantee the originally selected
> order?
> This is very important that it be in order from the original select
> statement as this is for paging. Adding an order by in the second
> select from the temp table will not fix the problem.

Once the data is in #TempPaging an ORDER BY will result in that
page being ordered. But that does not help if #TempPaging was not
loaded correctly.

> In this particular instance that I have reproduced we are using SQL 2005
> but have also seen this on SQL 2000 servers.

If you are on SQL 2005, the best is to use row_number():

SELECT OrderID, CustomerID, OrderDate, rowno
FROM (SELECT OrderID, CustomerID, OrderDate,
rowno = row_number() OVER
(PARTITION BY 1 ORDER BY CustomerID, OrderID)
FROM Northwind..Orders) AS x
WHERE rowno BETWEEN 100 AND 200
ORDER BY rowno

On SQL 2000 you can use a temp table table with an IDENTITY column,
and insert to that table with ORDER BY. I am told that this is
guaranteed to work, although I seem to recall that David claimed
to have seen conflicting testimony.

Note that this applies to INSERT only - it does *not* apply to SELECT INTO.

--
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|||Yes; shot you and replace you with a programmer who has read the first
10 pages of **any** RDBMS book. You are posting realllllllly baaaaad
questions. Please take some time to catch up over the weekend before
you ask us to do your job for you again.

SQL is a set-orient language. Tables -- by definition -- have no
ordering. That is the nature of a set. Have you ever read Dr. Codd's
12 rules for RDBMS/ Look up the Information Principle: all
relationships are shown as values in columns. Ordering is a
relationship, so you need a column(s) for it.

If you do not know who Dr. Codd is or his rules, then you are like a
Geometry student who never heard of Euclid.|||Celko,

Give the guy a break. Sheesh.

I'm beginning to think you are just an automated bot that jumps into
every conversation to complain and stir up the fire.|||Celko is right.. Big dumb mistake on my part. It does have an identity
column but for some reason I thought it was ordering by that by
default. It's not a misunderstanding of the way the world works, just a
mistake.|||pb648174 wrote:
> I have the following basic statements being executed:
> Create a temp table, #TempPaging
> Insert Into #TempPaging (Col1, Col2)
> Select Col1, Col2 From SomeOtherTable Order By Col2, Col1
> Select * from #TempPaging
> I can't provide a reproduceable scenario right now without making this
> into a 200K post, so I'm hoping someone will know what the issue is.. I
> can't find anything regarding this in BOL.
> Basically the order is off a little bit every now and then when there
> are large amounts of data, like more than a couple hundred rows. Is
> there something I need to do to guarantee the originally selected
> order?
> This is very important that it be in order from the original select
> statement as this is for paging. Adding an order by in the second
> select from the temp table will not fix the problem. In this particular
> instance that I have reproduced we are using SQL 2005 but have also
> seen this on SQL 2000 servers. I had previously asked this question as
> I was using a SELECT INTO statement, but now we are manually creating
> the temp table (Pain in the ass) and still having the same issue. Best
> case scenario is for it to work for a SELECT INTO.

In SQL 2005, use the RowNumber function in a nested sub query.

In SQL 2000, create enough index columns to handle your sort orders.

eg...
Select Mycol1, MyCol2, Mycol3,
MyIDX1 = Convert (Int, Null) ,
MyIDX2 = Convert (Int, Null) ,
MyIDX3 = Convert (Int, Null)
into #myResults
Select blah from whatever order by whatever

contrary to David Portas' assertion this does actually work most of the
time, however, I sure it can't be relied upon, though I've never seen
it fail...

Then, to have multiple order bys, and very very cheap and easy
pagination you then do.

Create Index #IDX1 on #myResults (Mycol1, Mycol2)
Create Index #IDX2 on #myResults (Mycol3, Mycol1)
Create Index #IDX3 on #myResults (Mycol2, Mycol3)
Followed by...

Declare @.Fred int
set @.Fred = 0
Update M
Set @.Fred = MyIDX1 = @.Fred + 1
>From #myResults M
With (Index = #IDX1)

set @.Fred = 0
Update M
Set @.Fred = MyIDX2 = @.Fred + 1
>From #myResults M
With (Index = #IDX2)

set @.Fred = 0
Update M
Set @.Fred = MyIDX3 = @.Fred + 1
>From #myResults M
With (Index = #IDX3)

Select *
>From #MyResults
Where IDX Between @.X1 And @.X2

> Any ideas?|||Erland Sommarskog wrote:
> pb648174 (google@.webpaul.net) writes:
> > I have the following basic statements being executed:
> > Create a temp table, #TempPaging
> > Insert Into #TempPaging (Col1, Col2)
> > Select Col1, Col2 From SomeOtherTable Order By Col2, Col1
> > Select * from #TempPaging
> > I can't provide a reproduceable scenario right now without making this
> > into a 200K post, so I'm hoping someone will know what the issue is.. I
> > can't find anything regarding this in BOL.
> > Basically the order is off a little bit every now and then when there
> > are large amounts of data, like more than a couple hundred rows. Is
> > there something I need to do to guarantee the originally selected
> > order?
> > This is very important that it be in order from the original select
> > statement as this is for paging. Adding an order by in the second
> > select from the temp table will not fix the problem.
> Once the data is in #TempPaging an ORDER BY will result in that
> page being ordered. But that does not help if #TempPaging was not
> loaded correctly.
> > In this particular instance that I have reproduced we are using SQL 2005
> > but have also seen this on SQL 2000 servers.
> If you are on SQL 2005, the best is to use row_number():
> SELECT OrderID, CustomerID, OrderDate, rowno
> FROM (SELECT OrderID, CustomerID, OrderDate,
> rowno = row_number() OVER
> (PARTITION BY 1 ORDER BY CustomerID, OrderID)
> FROM Northwind..Orders) AS x
> WHERE rowno BETWEEN 100 AND 200
> ORDER BY rowno
> On SQL 2000 you can use a temp table table with an IDENTITY column,
> and insert to that table with ORDER BY. I am told that this is
> guaranteed to work, although I seem to recall that David claimed
> to have seen conflicting testimony.

This isn't, though it is guaranteed to work in SQL 2005. afaik.

Creating an index on the chosen columns and then forcing the sliding
update statement
Update M Set @.Fred = Col = @.Fred + 1 From tabl M with (index=idxname)
is the only way I've ever seen it never fail for multi columns.

> Note that this applies to INSERT only - it does *not* apply to SELECT INTO.

That's interesting, I've found the exact opposite, so long as a table
scan is forced on the created table, I can't create temporary indexes
on a temporary table in 2000 if it's created with insert into select,
only with select into.

>
> --
> 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|||(drawnai@.hotmail.com) writes:
> Creating an index on the chosen columns and then forcing the sliding
> update statement
> Update M Set @.Fred = Col = @.Fred + 1 From tabl M with (index=idxname)
> is the only way I've ever seen it never fail for multi columns.

This is one more "works most of the time, but don't cry foul if it
doesn't". I see no point of using methods of which the result is
not defined.

>> Note that this applies to INSERT only - it does *not* apply to SELECT
>> INTO.
> That's interesting, I've found the exact opposite, so long as a table
> scan is forced on the created table, I can't create temporary indexes
> on a temporary table in 2000 if it's created with insert into select,
> only with select into.

Here is a quick example:

select IDENTITY(int, 1, 1) AS ident, OrderID = OrderID + 0,
CustomerID, OrderDate, ShipVia
into Orders
from Northwind..Orders Order by CustomerID, OrderID
go
SELECT * FROM Orders ORDER BY CustomerID, OrderID
go
TRUNCATE TABLE Orders
go
INSERT Orders (OrderID, CustomerID, OrderDate, ShipVia)
select OrderID = OrderID + 0, CustomerID, OrderDate, ShipVia
from Northwind..Orders
Order by CustomerID, OrderID
go
SELECT * FROM Orders ORDER BY CustomerID, OrderID
go
DROP TABLE Orders

It may not be the indexes you were talking about, but the result of a
query should never be dependent of the indexes on the table.

--
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|||drawnai@.hotmail.com wrote:
> In SQL 2005, use the RowNumber function in a nested sub query.
> In SQL 2000, create enough index columns to handle your sort orders.
> eg...
> Select Mycol1, MyCol2, Mycol3,
> MyIDX1 = Convert (Int, Null) ,
> MyIDX2 = Convert (Int, Null) ,
> MyIDX3 = Convert (Int, Null)
> into #myResults
> Select blah from whatever order by whatever
> contrary to David Portas' assertion this does actually work most of the
> time, however, I sure it can't be relied upon, though I've never seen
> it fail...

What assertion do you mean? All I said was tables are not ordered. They
are not. The example you posted above does not contradict me because
you specified ORDER BY, unlike the OP who had no ORDER BY in his SELECT
statement (only in the INSERT).

Your second example is more suspect. The behaviour of an assignment in
an UPDATE that references multiple rows is undefined.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||I'm sorry David, I'd just drank a couple of bottles of particularly
nice Castello Banfi, Brunello di Montalcino. Any provocative statements
I make during such inebriated times is purely to have a poke. I value
your opinions I assure you.

As for your comments about updates that affect multiple rows being
undefined, I'm afraid you're wrong.

Update table set @.fred = column = @.fred + 1 is defined in SQL server's
own help, please look it up if you don't believe me.

Not only that, but SQL Server evaluates columns in order (otherwise you
can't do order by 1, order by 2 etc.)

Thus, it's perfectly legal to do this...
declare @.rows int
Select a.Column1,
a.Column2,
b.Column3,
b.Column4.
c.Column5.
d.Column6,
sort1idx = convert (smallint, null)
sort2idx = convert (smallint, null)
sort3idx = convert (smallint, null)
into #results
>From A
Inner Join B on A.join = B.join
inner join C on C.join = b.join
Select @.rows = @.@.rowcount,
@.rc = @.@.error
create index #re1 on #results (column6, column3)
create index #re2 on #results (column2, column4)
create index #re1 on #results (column1, column5)

declare @.fred = int
set @.fred = 0
update R set @.fred = @.fred + 1, sort1idx = case when @.fred <= 1000 then
convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
(smallint, 2000 + @.rows - @.fred) else null end From #results R With
(index= #re1)
set @.fred = 0
update R set @.fred = @.fred + 1, sort2idx = case when @.fred <= 1000 then
convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
(smallint, 2000 + @.rows - @.fred) else null end From #results R With
(index= #re2)
set @.fred = 0
update R set @.fred = @.fred + 1, sort3idx = case when @.fred <= 1000 then
convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
(smallint, 2000 + @.rows - @.fred) else null end From #results R With
(index= #re3)

Select *
>From #results
where coalesce (sort1idx, sort2idx, sort3idx) Is not Null

-- This line returns the top and bottom 1000 by three dimensions (more
or less, I've been on Sauvignon Blanc in All bar one in Leicester
Square all night) and is the equivalent of SQL 2005's

Select t.Column1, t.column2, t.column3, t.column4, t.column5,
t.column6,
sort1idx = case when sort1idxasc + sort1idxdesc < 2002 then
sort1idxasc when sort1idxasc < 1001 then sort1idx when sort1idxasc >
1000 and sort1idxdesc > 1000 then null else 1000 + 1001 - sort1idxdesc
end, -- or something, I'm a bit pissed
sort2idx = etc...
sort3idx =
>From (
Select a.Column1,
a.Column2,
b.Column3,
b.Column4.
c.Column5.
d.Column6,
sort1idxasc = Row_number () (over column6, column3)
sort2idxasc = Row_number () (over column2, column4)
sort3idxasc = Row_number () (over column1, column5)
sort1idxasc = Row_number () (over column6 desc, column3 desc)
sort2idxasc = Row_number () (over column2 desc, column4 desc)
sort3idxasc = Row_number () (over column1 desc, column5 desc)
into #results
>From A
Inner Join B on A.join = B.join
inner join C on C.join = b.join) T Where sort1idxasc <= 1000 or
sort2idxasc <= 1000 or
sort3idxasc <= 1000 or
sort1idxdesc <= 1000 or
sort2idxdesc <= 1000 or
sort3idxdesc <= 1000)

It implements these with the same execution plan as it would a cursor.
I'm sure M. Ben Gan can confirm this.
The only difference is that SQL 2005 doesn't seem to need tempdb, and
it performs the work about 27% faster.|||Identity (1, 1) doesn't guarantee an ascending number by order, until
SQL 2005.|||drawnai@.hotmail.com wrote:
> I'm sorry David, I'd just drank a couple of bottles of particularly
> nice Castello Banfi, Brunello di Montalcino. Any provocative statements
> I make during such inebriated times is purely to have a poke. I value
> your opinions I assure you.
> As for your comments about updates that affect multiple rows being
> undefined, I'm afraid you're wrong.
> Update table set @.fred = column = @.fred + 1 is defined in SQL server's
> own help, please look it up if you don't believe me.
> Not only that, but SQL Server evaluates columns in order (otherwise you
> can't do order by 1, order by 2 etc.)
> Thus, it's perfectly legal to do this...
> declare @.rows int
> Select a.Column1,
> a.Column2,
> b.Column3,
> b.Column4.
> c.Column5.
> d.Column6,
> sort1idx = convert (smallint, null)
> sort2idx = convert (smallint, null)
> sort3idx = convert (smallint, null)
> into #results
> >From A
> Inner Join B on A.join = B.join
> inner join C on C.join = b.join
> Select @.rows = @.@.rowcount,
> @.rc = @.@.error
> create index #re1 on #results (column6, column3)
> create index #re2 on #results (column2, column4)
> create index #re1 on #results (column1, column5)
> declare @.fred = int
> set @.fred = 0
> update R set @.fred = @.fred + 1, sort1idx = case when @.fred <= 1000 then
> convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
> (smallint, 2000 + @.rows - @.fred) else null end From #results R With
> (index= #re1)
> set @.fred = 0
> update R set @.fred = @.fred + 1, sort2idx = case when @.fred <= 1000 then
> convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
> (smallint, 2000 + @.rows - @.fred) else null end From #results R With
> (index= #re2)
> set @.fred = 0
> update R set @.fred = @.fred + 1, sort3idx = case when @.fred <= 1000 then
> convert (smallint, @.fred) when @.rows - @.fred < 1000 then convert
> (smallint, 2000 + @.rows - @.fred) else null end From #results R With
> (index= #re3)
> Select *
> >From #results
> where coalesce (sort1idx, sort2idx, sort3idx) Is not Null
> -- This line returns the top and bottom 1000 by three dimensions (more
> or less, I've been on Sauvignon Blanc in All bar one in Leicester
> Square all night) and is the equivalent of SQL 2005's
> Select t.Column1, t.column2, t.column3, t.column4, t.column5,
> t.column6,
> sort1idx = case when sort1idxasc + sort1idxdesc < 2002 then
> sort1idxasc when sort1idxasc < 1001 then sort1idx when sort1idxasc >
> 1000 and sort1idxdesc > 1000 then null else 1000 + 1001 - sort1idxdesc
> end, -- or something, I'm a bit pissed
> sort2idx = etc...
> sort3idx =
> >From (
> Select a.Column1,
> a.Column2,
> b.Column3,
> b.Column4.
> c.Column5.
> d.Column6,
> sort1idxasc = Row_number () (over column6, column3)
> sort2idxasc = Row_number () (over column2, column4)
> sort3idxasc = Row_number () (over column1, column5)
> sort1idxasc = Row_number () (over column6 desc, column3 desc)
> sort2idxasc = Row_number () (over column2 desc, column4 desc)
> sort3idxasc = Row_number () (over column1 desc, column5 desc)
-- God I am a bit smashed. Went straight out onto the piss after
leaving the ofiice vandag.
-- into #results -- -dednae mean that.
> >From A
> Inner Join B on A.join = B.join
> inner join C on C.join = b.join) T Where sort1idxasc <= 1000 or
> sort2idxasc <= 1000 or
> sort3idxasc <= 1000 or
> sort1idxdesc <= 1000 or
> sort2idxdesc <= 1000 or
> sort3idxdesc <= 1000)
> It implements these with the same execution plan as it would a cursor.
> I'm sure M. Ben Gan can confirm this.
> The only difference is that SQL 2005 doesn't seem to need tempdb

(or at least its transaction log, half so much)
, and
> it performs the work about 27% faster.|||drawnai@.hotmail.com wrote:
> > As for your comments about updates that affect multiple rows being
> > undefined, I'm afraid you're wrong.
> > Update table set @.fred = column = @.fred + 1 is defined in SQL server's
> > own help, please look it up if you don't believe me.

There is a difference between valid syntax and defined behaviour. BOL
does indeed say that your syntax is valid but nowhere does it define
what the result is supposed to be. The closest the documentation gets
is where it describes the equivalent multiple row assignment in a
SELECT statement. It says:

"SELECT @.local_variable is typically used to return a single value into
the variable. However, when expression is the name of a column, it can
return multiple values. If the SELECT statement returns more than one
value, the variable is assigned the last value that is returned."

Note: "last value returned". That means the assignment only has to
happen once. The expression isn't necessarily evaluated for each row.
You cannot rely on the expression being evaluated for every row because
it doesn't always work.

In your example you try to force a particular execution plan onto your
code using an INDEX hint. But there is absolutely no reason why SQL
Server should always be required to implement a hint. Indexes are
intended as an optimization tool - they are not supposed to affect
logical behaviour of code.

So all I'm saying is that you should be very cautious with this UPDATE.
In the past we have seen too many undocumented features and smart
little tricks that fail or change in each new version. Unfortunately,
SQL Server is still full of "features" that give undefined results. If
you are doing a one-off update that doesn't matter much - you can
easily verify the results afterwards - but if you put this sort of
thing into production code you run the risk of it breaking under a
future version or service pack.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||David Portas (REMOVE_BEFORE_REPLYING_dportas@.acm.org) writes:
> In your example you try to force a particular execution plan onto your
> code using an INDEX hint. But there is absolutely no reason why SQL
> Server should always be required to implement a hint. Indexes are
> intended as an optimization tool - they are not supposed to affect
> logical behaviour of code.

I only like to enforce this: if the result of a query is dependent on
the presense of an index, the result of the query is undefined (or there
is a plain bug). The task of indexes is to decrease execution times, but
they should not affect the outcome of a query.

Of course, by adding an index hint you at least ensure that they query
will fail would the index be dropped. Then again, if someone changes
the index, you lose anyway.

--
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|||Erland Sommarskog wrote:
> David Portas (REMOVE_BEFORE_REPLYING_dportas@.acm.org) writes:
> > In your example you try to force a particular execution plan onto your
> > code using an INDEX hint. But there is absolutely no reason why SQL
> > Server should always be required to implement a hint. Indexes are
> > intended as an optimization tool - they are not supposed to affect
> > logical behaviour of code.
> I only like to enforce this: if the result of a query is dependent on
> the presense of an index, the result of the query is undefined (or there
> is a plain bug). The task of indexes is to decrease execution times, but
> they should not affect the outcome of a query.

I'm prepared to put up with checking a view queries once every new
generation
of SQL server, for an e-commerce site that will run on a laptop, rather
than
pay half a million quid for hardware licence fees, just to do it the
hard way.

> Of course, by adding an index hint you at least ensure that they query
> will fail would the index be dropped. Then again, if someone changes
> the index, you lose anyway.
>
> --
> 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|||David Portas wrote:

> In your example you try to force a particular execution plan onto your
> code using an INDEX hint. But there is absolutely no reason why SQL
> Server should always be required to implement a hint. Indexes are
> intended as an optimization tool - they are not supposed to affect
> logical behaviour of code.

I _am_ using it as an optimisation tool. I'm getting the results I
want, by forcing the
plan I want. If at some point, index hints stop working (like that's
going to happen,) I'll find some other way of breaking relational
theory.

What would be nice, (if you're listening Mr Gates,) is for you to
modify this mechanic so,
1. You can do it with selects as well.
2. The where clause checks @.variable conditions on every row, instead
of just at the beginning.

You really are taking this too seriously. The code works, and it's a
hundred times faster than the next nearest Oracle technique, and the
code has to be checked every now and then anyway, but so what? The cost
savings to market that this achieves more than outweighs the later
potential corrections.

If run forever reliability was the issue, I'm sure we can both agree
that we wouldn't
be using a product or suite of products written in c++ anyway.|||David Portas wrote:
> drawnai@.hotmail.com wrote:
> > > > As for your comments about updates that affect multiple rows being
> > > undefined, I'm afraid you're wrong.
> > > > Update table set @.fred = column = @.fred + 1 is defined in SQL server's
> > > own help, please look it up if you don't believe me.
> > There is a difference between valid syntax and defined behaviour. BOL

Defined behaviour is as defined behaviour does. Outperforming an
equivalent
query ten to one is worth a rewrite 5 years from now, in the unlikely
event
that microsoft, remove the ability. (This goes against all precedents
as MS
have done very little but improve ability rather than remove it.)

I understand your purist position though, I used to be a software
engineering
purist, but after 30 years of writing code, I now hold the cost benefit
analysis
position. If I can generate, orders, multidimensional rolling averages,
and all
kinds of crap with a single pass of a table, rather than generating a
gig of
transaction log, and 5 Gig of tempdb allocation, then I do it.

Similarly, if I can implement the kind of parametric query, like
dabs.com's have
done, and multiorder search facility, at basically no cost, then I do
it.

By the time MS remove this facility, they'll replace it with something
better,
so there's no worries.|||drawnai@.hotmail.com wrote:
> David Portas wrote:
> > drawnai@.hotmail.com wrote:
> > > > > > As for your comments about updates that affect multiple rows being
> > > > undefined, I'm afraid you're wrong.
> > > > > > Update table set @.fred = column = @.fred + 1 is defined in SQL server's
> > > > own help, please look it up if you don't believe me.
> > > > There is a difference between valid syntax and defined behaviour. BOL
> Defined behaviour is as defined behaviour does. Outperforming an
> equivalent
> query ten to one is worth a rewrite 5 years from now, in the unlikely
> event
> that microsoft, remove the ability. (This goes against all precedents
> as MS
> have done very little but improve ability rather than remove it.)
> I understand your purist position though, I used to be a software
> engineering
> purist, but after 30 years of writing code, I now hold the cost benefit
> analysis
> position. If I can generate, orders, multidimensional rolling averages,
> and all
> kinds of crap with a single pass of a table, rather than generating a
> gig of
> transaction log, and 5 Gig of tempdb allocation, then I do it.
> Similarly, if I can implement the kind of parametric query, like
> dabs.com's have
> done, and multiorder search facility, at basically no cost, then I do
> it.
> By the time MS remove this facility, they'll replace it with something
> better,
> so there's no worries.

I don't consider myself a purist. In the spirit of Martin Fowler I
guess my ethic is something like "Any fool can write something that
works. Good developers write stuff that is verifiable and supportable."
That's not dogmatic. It's entirely practical because it reduces TCO for
the customer.

In this case the problem is not just that it may break in some distant
future. It is broken now. That is, even today there are situations
where multiple row variable assignments in queries just do not happen.
Since you can't predict whether those situations will arise at runtime
you have to take a calculated risk before you implement those
undocumented tricks. Microsoft's history of breaking changes to
undocumented behaviour is against you. I can think of multiple
precedents where undefined features have changed or failed in SQL
Server service packs, hotfixes and versions. The customer then has to
pay the price for development before he can patch his server.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||(drawnai@.hotmail.com) writes:
> Defined behaviour is as defined behaviour does. Outperforming an
> equivalent query ten to one is worth a rewrite 5 years from now, in the
> unlikely event that microsoft, remove the ability.

But the ability isn't there. It only looks like it is. That's why it's
undefined.

In SQL Server 6.5 GROUP BY implied an ORDER BY. Not so any more. In SQL 2000
people would put TOP 100 PERCENT ORDER BY in a view, and they found that
they did seem to need an ORDER BY when selecting from the view. In SQL 2005
more than one have found that they don't get away with it.

You get the result you get by happenstance. There is nothing that Microsoft
can remove, because they never added it. One day the optimizer decides to
do a different plan, and you don't get the result you wanted.

Of course, you may be prepared to take the gamble, but the day it breaks,
it's going to break hard.

--
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|||Erland Sommarskog wrote:
> (drawnai@.hotmail.com) writes:
> > Defined behaviour is as defined behaviour does. Outperforming an
> > equivalent query ten to one is worth a rewrite 5 years from now, in the
> > unlikely event that microsoft, remove the ability.
> But the ability isn't there. It only looks like it is. That's why it's
> undefined.
> In SQL Server 6.5 GROUP BY implied an ORDER BY. Not so any more. In SQL 2000
> people would put TOP 100 PERCENT ORDER BY in a view, and they found that
> they did seem to need an ORDER BY when selecting from the view. In SQL 2005
> more than one have found that they don't get away with it.
> You get the result you get by happenstance. There is nothing that Microsoft
> can remove, because they never added it. One day the optimizer decides to
> do a different plan, and you don't get the result you wanted.
> Of course, you may be prepared to take the gamble, but the day it breaks,
> it's going to break hard.

Everything you say is true. I don't disagree with any of it. However,
from experience,
an ordered update against a single table is worth the risk, that I
might have to (one day) rewrite it. I'm not writing space targeted
software (anymore.)

I find this particularly the case, because I've never seen an explicit
index hint against
a single table, to be ignored. Similarly, microsoft actually advertise
the update set
@.fred = col = @.fred + 1.

I feel justified in my assertion that "by the time they don't support
it, they'll have introduced something faster," because on the whole,
(and very definitely in this case)
they have done.

Most tech authorities hold that 2 second is an acceptable response time
for a webpage. I maintain that anything over 40 mS is failure.

As for "It may not work at sometime in the future." Well that's the
most ridiculous strawman I've heard in a long time.

I judge that keeping an eye on code is an ongoing requirement, and I
constantly watch for changes that invalidate something I depend on.

>From .net 1.1, to .net 2.0 invoking the Sleep method, meant a change
from a class member, to a static member, meaning only a thread can
sleep itself. I don't see my watching for changes to unlisted features
to be any different to changes to listed features.

>
> --
> 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|||David Portas wrote:
> drawnai@.hotmail.com wrote:
> > David Portas wrote:
> > > drawnai@.hotmail.com wrote:
> > > > > > > > As for your comments about updates that affect multiple rows being
> > > > > undefined, I'm afraid you're wrong.
> > > > > > > > Update table set @.fred = column = @.fred + 1 is defined in SQL server's
> > > > > own help, please look it up if you don't believe me.
> > > > > > > There is a difference between valid syntax and defined behaviour. BOL
> > Defined behaviour is as defined behaviour does. Outperforming an
> > equivalent
> > query ten to one is worth a rewrite 5 years from now, in the unlikely
> > event
> > that microsoft, remove the ability. (This goes against all precedents
> > as MS
> > have done very little but improve ability rather than remove it.)
> > I understand your purist position though, I used to be a software
> > engineering
> > purist, but after 30 years of writing code, I now hold the cost benefit
> > analysis
> > position. If I can generate, orders, multidimensional rolling averages,
> > and all
> > kinds of crap with a single pass of a table, rather than generating a
> > gig of
> > transaction log, and 5 Gig of tempdb allocation, then I do it.
> > Similarly, if I can implement the kind of parametric query, like
> > dabs.com's have
> > done, and multiorder search facility, at basically no cost, then I do
> > it.
> > By the time MS remove this facility, they'll replace it with something
> > better,
> > so there's no worries.
> I don't consider myself a purist. In the spirit of Martin Fowler I
> guess my ethic is something like "Any fool can write something that
> works. Good developers write stuff that is verifiable and supportable."
> That's not dogmatic. It's entirely practical because it reduces TCO for
> the customer.
> In this case the problem is not just that it may break in some distant
> future. It is broken now. That is, even today there are situations
> where multiple row variable assignments in queries just do not happen.

Are you saying my query doesn't work? No? I didn't think so.

> Since you can't predict whether those situations will arise at runtime
> you have to take a calculated risk before you implement those

Not true. I actually run them to find out.

> undocumented tricks. Microsoft's history of breaking changes to

Not so far. Nothing I've written in the last ten years has been broken
by a change anywhere near so much as those broken by changes to
advertised features.

> undocumented behaviour is against you. I can think of multiple
> precedents where undefined features have changed or failed in SQL
> Server service packs, hotfixes and versions. The customer then has to
> pay the price for development before he can patch his server.

We agree then. Like I said, it's a pure cost benefit analysis. You
contend that
this approach has risks, but imply that I'm not aware of that. This is
simply
not true. I'm well aware of the risks, which is why I have a list of
features I
use that are periodically checked. This includes documented features.

In fact in my experience, documented features change more than
undocumented
features.

> --
> David Portas, SQL Server MVP
> Whenever possible please post enough code to reproduce your problem.
> Including CREATE TABLE and INSERT statements usually helps.
> State what version of SQL Server you are using and specify the content
> of any error messages.
> SQL Server Books Online:
> http://msdn2.microsoft.com/library/...US,SQL.90).aspx
> --|||drawnai@.hotmail.com wrote:
> Are you saying my query doesn't work? No? I didn't think so.

I'm saying you can't demonstrate that it does.

> > Since you can't predict whether those situations will arise at runtime
> > you have to take a calculated risk before you implement those
> Not true. I actually run them to find out.

Which proves nothing because execution plans can change at runtime.

> I'm well aware of the risks, which is why I have a list of
> features I
> use that are periodically checked. This includes documented features.

Proves nothing. See above.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||David Portas wrote:
> drawnai@.hotmail.com wrote:
> > Are you saying my query doesn't work? No? I didn't think so.
> I'm saying you can't demonstrate that it does.
> > > Since you can't predict whether those situations will arise at runtime
> > > you have to take a calculated risk before you implement those
> > Not true. I actually run them to find out.
> Which proves nothing because execution plans can change at runtime.
> > I'm well aware of the risks, which is why I have a list of
> > features I
> > use that are periodically checked. This includes documented features.
> Proves nothing. See above.

Neither does it if it's written down.

> --
> David Portas, SQL Server MVP
> Whenever possible please post enough code to reproduce your problem.
> Including CREATE TABLE and INSERT statements usually helps.
> State what version of SQL Server you are using and specify the content
> of any error messages.
> SQL Server Books Online:
> http://msdn2.microsoft.com/library/...US,SQL.90).aspx
> --|||what happens if the table is big and this UPDATE is executed by several
processors in parallel?|||I'm well aware of Codd, thank you very much. I'm also aware that SQL is
a relational language.

Ordering is however, a requirement for the real world, and I take
advantage of all the features of an application that are published,
and also the features that I deem are safe, that aren't published.

It's interesting you say that I could be replaced, because in 14 years
as a contractor, I've never (that's Never) failed to deliver working
project, as advertised. I've until very recently, deliberately gone
into each project as junior developer, taken over, and then fixed it,
and am usually the last contractor standing. I have prototypes I've
written, that became airborne software, and are flying, in space, as
well as in the air, and I replaced the whole of site server and 150
pages of ASP, with a single stored procedure for a very busy (and
successful) website.
This single stored procedure contained ALL the business logic. It was
done, because it needed to work, and the company couldn't get the
people in time to write it. This ran for two years before I was
replaced (correctly I believe) with a net datatable multi-tier based
system, once there was sufficient resource to continue with
development.

Books are useful to be sure, and I do have an extensive library on
software engineering, but a book is only as good as its authors are
clever. I'm happy to stand by my record, of having never failed to
deliver.|||When the day comes that Microsoft runs parallel query against a
sequential update, then it will be spotted in UAT (if I haven't already
seen it,) and replaced with a cursor or some other cunning tactic.

I don't imagine I'll ever see that however, because I don't suppose
that Microsoft will rollback the row_number() (Over col1, col2, col3)
function in SQL 2010, just to allow it to introduce its new "parallel
sequential (tm)" technology - a process that allocates an unknown in
advance amount sequential numbers of in parallel.

Out of interest, how does one allocate an index in sequence in parallel
against a table whose size is unknown at the start of the update
without wasting huge resources calculating the tree sizes? Does one
mark the entire index as "untouched", then excute massive parallel jobs
against parts of it, ensuring never to touch the same record twice?
Perhaps, it asks god how big each table leaf root is, and then assigns
ranges of numbers of exact size, (taking into account any inserts or
deletes that are going to happen, after it starts and before it ends)
to ensure that when it distributes the job to it's SMP array, that each
row gets a number that is exactly unique, and contiguous. Perhaps you
could start at one end of the table, with the length of it (including
any intermediate insert/deletes as extrapolated from a small piece of
fairy cake), and start at the other end of the same, and then work
inwards.

My solution would be to simply use magic. This is guaranteed to work.|||drawnai@.hotmail.com wrote:
> When the day comes that Microsoft runs parallel query against a
> sequential update, then it will be spotted in UAT (if I haven't already
> seen it,) and replaced with a cursor or some other cunning tactic.
> I don't imagine I'll ever see that however, because I don't suppose
> that Microsoft will rollback the row_number() (Over col1, col2, col3)
> function in SQL 2010, just to allow it to introduce its new "parallel
> sequential (tm)" technology - a process that allocates an unknown in
> advance amount sequential numbers of in parallel.
> Out of interest, how does one allocate an index in sequence in parallel
> against a table whose size is unknown at the start of the update
> without wasting huge resources calculating the tree sizes? Does one
> mark the entire index as "untouched", then excute massive parallel jobs
> against parts of it, ensuring never to touch the same record twice?
> Perhaps, it asks god how big each table leaf root is, and then assigns
> ranges of numbers of exact size, (taking into account any inserts or
> deletes that are going to happen, after it starts and before it ends)
> to ensure that when it distributes the job to it's SMP array, that each
> row gets a number that is exactly unique, and contiguous. Perhaps you
> could start at one end of the table, with the length of it (including
> any intermediate insert/deletes as extrapolated from a small piece of
> fairy cake), and start at the other end of the same, and then work
> inwards.
> My solution would be to simply use magic. This is guaranteed to work.

Even sequential scans don't always start at the same place in the index
due to enhanced read-ahead (AKA merry-go-round scan). AFAIK that
doesn't apply to index updates today but it could perhaps do so in
future. That's a good example of something you may be unlikely to spot
in a unit test (unless you simulate load). It will likely show up if
you test to peak production workload but do you always regression test
on that scale for every service pack? Engine changes have gone in SPs
before.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/...US,SQL.90).aspx
--|||David Portas wrote:
> drawnai@.hotmail.com wrote:
> > When the day comes that Microsoft runs parallel query against a
> > sequential update, then it will be spotted in UAT (if I haven't already
> > seen it,) and replaced with a cursor or some other cunning tactic.
> > I don't imagine I'll ever see that however, because I don't suppose
> > that Microsoft will rollback the row_number() (Over col1, col2, col3)
> > function in SQL 2010, just to allow it to introduce its new "parallel
> > sequential (tm)" technology - a process that allocates an unknown in
> > advance amount sequential numbers of in parallel.
> > Out of interest, how does one allocate an index in sequence in parallel
> > against a table whose size is unknown at the start of the update
> > without wasting huge resources calculating the tree sizes? Does one
> > mark the entire index as "untouched", then excute massive parallel jobs
> > against parts of it, ensuring never to touch the same record twice?
> > Perhaps, it asks god how big each table leaf root is, and then assigns
> > ranges of numbers of exact size, (taking into account any inserts or
> > deletes that are going to happen, after it starts and before it ends)
> > to ensure that when it distributes the job to it's SMP array, that each
> > row gets a number that is exactly unique, and contiguous. Perhaps you
> > could start at one end of the table, with the length of it (including
> > any intermediate insert/deletes as extrapolated from a small piece of
> > fairy cake), and start at the other end of the same, and then work
> > inwards.
> > My solution would be to simply use magic. This is guaranteed to work.
> Even sequential scans don't always start at the same place in the index
> due to enhanced read-ahead (AKA merry-go-round scan). AFAIK that
> doesn't apply to index updates today but it could perhaps do so in
> future. That's a good example of something you may be unlikely to spot
> in a unit test (unless you simulate load). It will likely show up if
> you test to peak production workload but do you always regression test
> on that scale for every service pack? Engine changes have gone in SPs
> before.

And will no doubt go further in future, due to the new CTP approach to
delivery.

> --
> David Portas, SQL Server MVP
> Whenever possible please post enough code to reproduce your problem.
> Including CREATE TABLE and INSERT statements usually helps.
> State what version of SQL Server you are using and specify the content
> of any error messages.
> SQL Server Books Online:
> http://msdn2.microsoft.com/library/...US,SQL.90).aspx
> --|||--CELKO-- wrote:
> Yes; shot you and replace you with a programmer who has read the first
> 10 pages of **any** RDBMS book. You are posting realllllllly baaaaad
> questions. Please take some time to catch up over the weekend before
> you ask us to do your job for you again.
> SQL is a set-orient language. Tables -- by definition -- have no
> ordering. That is the nature of a set. Have you ever read Dr. Codd's
> 12 rules for RDBMS/ Look up the Information Principle: all
> relationships are shown as values in columns. Ordering is a
> relationship, so you need a column(s) for it.
> If you do not know who Dr. Codd is or his rules, then you are like a
> Geometry student who never heard of Euclid.

When faced with crass pointless comments like this, it's unsurprising
that
software engineering doesn't advance as fast as it could. Relational
theory is
no cleverer than Codd, (and maybe Date) was. They weren't gods. They
put forward
software engineering maybe only twice as far as Straustrup put it back
with
the abomination of c++.

I'm happy to decline to Bruce Lee. No matter how good a technique, be
it a
punch or a throw or a kick, (or relational theory, or xml, or
hibernate, or a
standards document) it becomes a weakness when one becomes obsessed
with it.