I agree, this is the most readable, AND it works
mister.magoo (4/26/2013)
Personally, for readability and your specific requirement, as long as you can guarantee the data type for PathIDs 30 and 31, then you can use this:
select DataId, PathId, Value
from dbo.TestTable
WHERE
PathID in (30,31)
AND
CASE
WHEN PathID in (30,31) THEN CONVERT(NUMERIC(14,2),Value)
ELSE 0
END <> 0;
I think this is logically the same as the "bombproof" query I posted earlier (even though the plan for my version includes a compute scalar) - the code in the CROSS APPLY can be dropped down to the WHERE clause:
SELECT
DataId,
Value,
x.NumericValue
FROM #Test
CROSS APPLY (
SELECT [NumericValue] = CASE
WHEN PathID in (30,31) THEN CAST(Value AS NUMERIC(10,2))
ELSE 0 END
) x
WHERE PathID in (30,31)
AND [NumericValue] <> 0
SELECT
DataId,
Value,
NumericValue = CAST(Value AS NUMERIC(10,2))
FROM #Test
WHERE PathID in (30,31)
AND CASE
WHEN PathID in (30,31) THEN CAST(Value AS NUMERIC(10,2))
ELSE 0 END <> 0
The end result is the same – value is only CAST and compared in a single expression which includes the numeric check:
([tempdb].[dbo].[#Test].[PathID]=(30) OR [tempdb].[dbo].[#Test].[PathID]=(31))
AND CASE
WHEN [tempdb].[dbo].[#Test].[PathID]=(31) OR [tempdb].[dbo].[#Test].[PathID]=(30)
THEN CONVERT(numeric(14,2),[tempdb].[dbo].[#Test].[Value],0)
ELSE (0.00) END
<>(0.00)
Your version also works if the datatype for PathID is changed to VARCHAR:
DROP TABLE #Test
CREATE TABLE #Test (DataId INT IDENTITY (23,6921), [PathID] VARCHAR(2), Value VARCHAR(25))
INSERT INTO #Test (PathID, Value) VALUES
(30, '3.14'),
(29, 'Twenty seven'),
(32,'24/04/2013'),
(31,'100'),
(7,'Yesterday'),
(30,'0')
select DataId, PathId, Value
from #Test
WHERE
PathID in (30,31)
AND
CASE
WHEN PathID in (30,31) THEN CONVERT(NUMERIC(14,2),Value)
ELSE 0
END <> 0;
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
ChrisM@Work (4/26/2013)
I think this is logically the same as the "bombproof" query I posted earlier (even though the plan for my version includes a compute scalar) - the code in the CROSS APPLY can be dropped down to the WHERE clause:
...
The end result is the same – value is only CAST and compared in a single expression which includes the numeric check:
Absolutely, yes - I agree - just wanted to offer that as an alternative "code format", but your "Bombproof" code removes the need for my caveat of "as long as you can guarantee the data type", so in the end I would probably use yours anyway because I like to be assured of that sort of thing by the code, not by the person...
MM
select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);
ChrisM@Work (4/26/2013)
- how can it fail?
That can't. My apologies. I rushed myself and didn't really think it through. Thanks for taking the time to show me in a slightly different way. It's penetrated my thick skull now.
That's interesting. I've not used this query hint before, but understood that it operated on the order of joins in the FROMlist, rather than the order of searches in a predicate.
Well, because the join list is forced, the subqueries are supposed to be ran in their order so nothing 'leaks out' into the main query. Unfortunately, predicates are leaking 'into' the earlier query, as you've shown (and is repeatable on my system).
I need to go back to the drawing boards on a few queries I've built this way and fix them. Apparently I've been getting lucky, because I've used this as a fix in a number of places. I'm wondering if it's because it's just the single 'inner query' and if it's because there's no join order to actually force it to calculate, but even some manipulation on that idea doesn't function.
DROP TABLE #Test
CREATE TABLE #Test (ID INT IDENTITY (23,6921), [PathID] INT, Value VARCHAR(25))
INSERT INTO #Test (PathID, Value) VALUES
(30, '3.14'),
(29, 'Twenty seven'),
(32,'24/04/2013'),
(31,'100'),
(7,'Yesterday'),
(30,'0')
SELECT
a.id,
CONVERT( NUMERIC(10,2), a.Value) AS NumValue
FROM
(SELECT DISTINCT id FROM #Test) AS b
JOIN
(SELECT
id,
Value
FROM
#Test
WHERE
ISNUMERIC( Value) = 1
) AS a
ON b.id = a.id
WHERE
CONVERT( NUMERIC(10,2), a.Value) <> 0
OPTION (FORCE ORDER)
Sorry about that Chris. I'll be over there hashing things out with some beer popsicles and dust bunnies if I can get Jeff to lend me them. That was an abrupt awakening that I'm doing things wrong... Appreciate it.
Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.
For better assistance in answering your questions[/url] | Forum Netiquette
For index/tuning help, follow these directions.[/url] |Tally Tables[/url]
Twitter: @AnyWayDBA
Evil Kraig F (4/26/2013)
...Thanks for taking the time to show me in a slightly different way...
Welcome. It's one of those things we take for granted after a while, not really thinking about it but knowing intuitively "I can't do it like that, it doesn't work!"
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
Viewing 9 posts - 16 through 24 (of 24 total)
You must be logged in to reply to this topic. Login to reply