May 13, 2008 at 2:57 pm
srienstr (5/13/2008)
Danielle:Don't bother with the loop at all, substitute in a join.
----Segment Level Supply
INSERT INTO @ConversionTesting(Quarter, Source, Segment, Metric,Value)
select Q.Quarter, 'Converted' as Source, MarketsegmenttypeCode, 'Inventory', sum(NumUnits)
from dbo.tbl_BldgSegments bs
inner join lt_marketsegmenttype mst
on bs.marketsegmenttypeid = mst.marketsegmenttypeid
inner join tbl_Building b
on bs.buildingid = b.buildingid
inner join tbl_Property p
on b.propertyid = p.propertyid
cross join @DistinctQuarters Q
where legacymsacode = CASE @MSA_Code WHEN 0 THEN legacymsacode ELSE @MSA_Code END and
(bs.SurveyDate = q.Quarter
or (bs.SurveyDate < q.Quarter and (bs.TerminateDate is null OR BS.TerminateDate > q.Quarter)))
group by MarketsegmenttypeCode
Why do you need a Cross-Join on the @DistinctQuarters table?
--Jeff Moden
Change is inevitable... Change for the better is not.
May 13, 2008 at 3:18 pm
Jeff Moden (5/13/2008)
Why do you need a Cross-Join on the @DistinctQuarters table?
From my read of the code, it appeared to be storing (or intended to store) multiple time frames, with each one producing a row in the output table. Using the cross join seemed to simplest way to maintain the same output.
Now that I think more on it, would it run more efficiently using a non-equijoin, or will the optimizer handle that from the where criteria?
May 13, 2008 at 3:22 pm
dporter (5/13/2008)
Thank you so much! This took about 10 seconds off of my query. Thanks! 🙂
Out of curiosity, what is the current time and what was the previous time for this section of code? Taking 10 out of 13 is much more satisfying than 10 out of 120.
May 13, 2008 at 4:24 pm
srienstr (5/13/2008)
Jeff Moden (5/13/2008)
Why do you need a Cross-Join on the @DistinctQuarters table?From my read of the code, it appeared to be storing (or intended to store) multiple time frames, with each one producing a row in the output table. Using the cross join seemed to simplest way to maintain the same output.
Now that I think more on it, would it run more efficiently using a non-equijoin, or will the optimizer handle that from the where criteria?
I believe you'll find that the criteria you included will turn the cross-join into a simple inner join... why not just call it that way?
--Jeff Moden
Change is inevitable... Change for the better is not.
May 15, 2008 at 1:25 pm
Excellent article--clear and concise.
(1) I recently wrote an arn article that might interest you and readers of your article, entitled "Bring Array Mapping Capabilities to SQL" available at http://www.devx.com/dbzone/Article/35790
(2) Your solution to the "split string on commas" using the tally table is sub-optimal, as I am sure you are aware. Perhaps you were trying to mirror the looping solution, but it might also pay to show the cleaner tally solution (you incorporate this into your next example but it might be helpful to others to see it standalone):
DECLARE @Parameter VARCHAR(8000)
SET @Parameter = ',Element01,Element02,Element03,Element04,Element05,'
SELECT N, SUBSTRING(@Parameter,N+1,CHARINDEX(',',@Parameter,N+1)-N-1)
FROM dbo.Tally
WHERE N < LEN(@Parameter)
AND SUBSTRING(@Parameter,N,1) = ','
ORDER BY N
May 15, 2008 at 4:07 pm
Looks interesting... can't download the code, though, because I'm not a member and they want too much info for my liking.
--Jeff Moden
Change is inevitable... Change for the better is not.
May 16, 2008 at 9:52 am
Jeff Moden (5/15/2008)
Looks interesting... can't download the code, though, because I'm not a member and they want too much info for my liking.
Jeff, I was able to download the code and I am not a member. I have attached it for you.
Ian.
"If you are going through hell, keep going."
-- Winston Churchill
May 16, 2008 at 2:10 pm
Thanks, Ian, for sending the code bundle along.
May 16, 2008 at 2:29 pm
No, problem. I don't know why Jeff wasn't able to get it, unless they could sense who he is and realized he is so good that he doesn't need the code! :w00t:
Ian.
"If you are going through hell, keep going."
-- Winston Churchill
May 16, 2008 at 5:13 pm
Ian Crandell (5/16/2008)
Jeff Moden (5/15/2008)
Looks interesting... can't download the code, though, because I'm not a member and they want too much info for my liking.Jeff, I was able to download the code and I am not a member. I have attached it for you.
Must be because I won't take cookies, either... :hehe:
--Jeff Moden
Change is inevitable... Change for the better is not.
May 16, 2008 at 5:38 pm
Ian Crandell (5/16/2008)
No, problem. I don't know why Jeff wasn't able to get it, unless they could sense who he is and realized he is so good that he doesn't need the code! :w00t:
Heh... Must've been my computer that did it... it's kind'a allergic to While loops. Thanks for downloading and posting the code, Ian. 🙂
--Jeff Moden
Change is inevitable... Change for the better is not.
May 16, 2008 at 5:40 pm
Michael,
It'll take me a bit to digest the "Map", but very nice on the documentation! Nice to see something so well documented!
--Jeff Moden
Change is inevitable... Change for the better is not.
May 17, 2008 at 8:19 am
Just an FYI: I realized the error of my ways in nomenclature: my next release (due out the end of May) will rename SP_map to just Map. Should not have used the prefix.
May 22, 2008 at 8:57 am
All right Jeff, I was having fun with your tally table example and trying to think set-based on how to clean up a column that included non-alpha characters. I figured it out, but now my pea-brain is stumped as to how the reconstruction of the string is occurring. How does SQL know to piece this back together in its entirety in one SELECT, without having to go through a WHILE loop OR join to a Tally Table? (I left in what I thought I was going to have to do, commented out, which I figured out I didn't need, but am not sure why)
Thanks!
--=============================================================================
-- Create and populate a Tally table --By Jeff Moden, 2008/05/07 http://www.sqlservercentral.com
--=============================================================================
--===== Conditionally drop and create the table/Primary Key
IF OBJECT_ID('Tempdb..#Tally') IS NOT NULL BEGIN DROP TABLE #Tally END
CREATE TABLE #Tally (N INT)
--===== Create and preset a loop counter
DECLARE @Counter INT, @upperLimit INT
SET @Counter = 1
SET @upperLimit = 11000 -- 5-19-08 Jon Crawford - change parameter here for upperLimit, rather than hard-coding
--===== Populate the table using the loop and counter
WHILE @Counter <= @upperLimit
BEGIN
INSERT INTO #Tally (N) VALUES (@Counter)
SET @Counter = @Counter + 1
END
--===========================================END TALLY TABLE SETUP========================================
IF object_id('Tempdb..#MyHead') IS NOT NULL BEGIN DROP TABLE #MyHead END
CREATE TABLE #MyHead
(PK INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
theValue VARCHAR(500))
INSERT INTO #MyHead
SELECT 'The 10/quick 1/brown 2008fox' UNION ALL
SELECT ' jumped over 9' UNION ALL
SELECT 'the/ lazy ' UNION ALL
SELECT 'd0og'
SELECT * from #MyHead
IF object_id('Tempdb..#holdMe') IS NOT NULL BEGIN DROP TABLE #holdMe END
SELECT N,
mh.PK row,
substring(mh.theValue,N,1) value
INTO #holdMe
FROM #MyHead mh
CROSS JOIN #Tally
WHERE N < LEN(mh.theValue)+2
AND substring(mh.theValue,N,1) NOT LIKE '[0-9/]'
ORDER BY mh.PK,N
SELECT * FROM #holdMe
DECLARE @rebuildMe varchar(2000), @iteration int
SET @rebuildMe = ''
--SET @iteration = 1
--WHILE len(@rebuildMe)<(SELECT Max(N) FROM #holdMe)
--BEGIN
SELECT @rebuildMe = @rebuildMe + #holdMe.value
FROM #holdMe --CROSS JOIN #Tally
--WHERE #Tally.N<2--(SELECT max(N) FROM #holdMe)+1
--ORDER BY #Tally.N, #holdMe.row
--SET @iteration = @iteration + 1
--END
SELECT @rebuildMe
---------------------------------------------------------
How best to post your question[/url]
How to post performance problems[/url]
Tally Table:What it is and how it replaces a loop[/url]
"stewsterl 80804 (10/16/2009)I guess when you stop and try to understand the solution provided you not only learn, but save yourself some headaches when you need to make any slight changes."
May 22, 2008 at 11:17 am
Using your test data, what would you expect this to return?
DECLARE @rebuildMe varchar(2000), @iteration int
SET @rebuildMe = ''
SELECT @rebuildMe = @rebuildMe + cast(n as varchar(10)) + ' '
FROM #tally
SELECT @rebuildMe
Dave J
Viewing 15 posts - 136 through 150 (of 511 total)
You must be logged in to reply to this topic. Login to reply