User not logged in - login - register
Home Calendar Books School Tool Photo Gallery Message Boards Users Statistics Advertise Site Info
go to bottom | |
 Message Boards » » ]More SQL questions! Page [1]  
aaronburro
Sup, B
53065 Posts
user info
edit post

OK, I'm feeling really dumb right now. I've got a View, as so:

--------------
Facility
Characterization
Revision
EffectiveDate
...
LastDate
--------------

Basically, I want to find the revision for a characterization and facility with the highest effective date such that a given date falls between EffectiveDate and LastDate. if LastDate is NULL, I assume that it is greater than the given date.

Here is the query I have come up with.
Quote :
"
SELECT
B.Facility,
B.Characterization,
B.Revision,
B.EffectiveDate,
B.LastDate
FROM
(SELECT
Facility,
Characterization,
MAX (EffectiveDate) AS Highest
FROM
View_CharacterizationRevisions
WHERE
EffectiveDate <= @Date AND
((LastDate IS NULL) OR (LastDate >= @Date))
GROUP BY
Facility,
Characterization) A,
View_CharacterizationRevisions B
WHERE
A.Facility = B.Facility AND
A.Characterization = B.Characterization AND
Highest = B.EffectiveDate
"


This seems awfully complicated. is there a better way to do this so that I don't have to use two freaking SELECT statements? I seem to recall that there was a way I could get the maximum of a group, but when I try that, it always makes me put every stupid field into the GROUP BY clause, which ends up giving me the wrong result. This query is going to run on MS SQL 2005.

2/4/2010 1:22:57 PM

1985
All American
2175 Posts
user info
edit post

If the entries are unique per date, you can just do top 1 and order by date desc

[Edited on February 4, 2010 at 1:34 PM. Reason : h]

2/4/2010 1:34:01 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

haha, I did use that for one, but i should have mentioned that I would also like to run this for all characterizations, too. In other words, I'd like to know the revision for each characterization and facility combination that has the highest effective date that matches the WHERE clause. And, effective dates are NOT guaranteed to be unique, for what it's worth

2/4/2010 1:39:37 PM

Golovko
All American
27023 Posts
user info
edit post

Quote :
"OK, I'm feeling really dumb right now"


Is that because you made a SQL thread when there already is one?

2/4/2010 2:03:41 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

there are trillions, lol. I didn't see any current ones

2/4/2010 2:18:03 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

Mind posting any sample data and the desired result set? I dont get your explanation very well.

2/4/2010 2:19:49 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

Sure. Let's assume facility is always constant...

Row  Characterization     Revision     EffectiveDate          LastDate
--- ---------------- -------- ------------- -------------
1 Apples 0 01/01/2001 11/01/2002
2 Apples 1 02/04/2004 NULL
3 Apples 2 10/15/2002 NULL
4 Oranges 0 05/03/1984 NULL
5 Bananas 0 06/25/1981 01/01/2009
6 Bananas 1 01/01/2009 NULL


If I pass a date of 10/16/2002, I expect rows 3, 4, and 5 to be returned, for instance
If I pass a date of 3/15/2009, I expect rows 2, 3, and 6 to be returned.

2/4/2010 2:34:28 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

In the second example, did you mean you expect 2, 4, and 6?

2/4/2010 2:51:05 PM

disco_stu
All American
7436 Posts
user info
edit post

SELECT
fields
FROM
table
WHERE
date >= EffectiveDate AND date <= COALESCE(LastDate, '12/31/9999')

This will turn NULL LastDates into 12/31/9999.

Which granted will give your query a Y10k bug, but hey, SQL doesn't currently support dates past 9999 anyway. Assuming humanity will even use a decimal calendar at that point.

[Edited on February 4, 2010 at 3:52 PM. Reason : y10k]

2/4/2010 3:35:45 PM

Novicane
All American
15416 Posts
user info
edit post

i can hear the programmers in Y10K bitching already at you.

2/4/2010 4:20:44 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

wolfmarsh, yeah, 2,4,6 is right.

^^ so that's what coalesce does... interesting. How is that helping to find the MAX(EffectiveDate), though? Is it?

2/4/2010 6:08:11 PM

disco_stu
All American
7436 Posts
user info
edit post

I'm confused; do you want to feed it a date and then determine if that date is after the latest effective date in the table? I thought that you simply wanted records that were between to dates where the end date could be null and null dates should be ignored.

Coalesce effectively converts nulls but what it's really doing is returning the first non-null value in the list you provide.

[Edited on February 4, 2010 at 6:51 PM. Reason : Coalesce ]

2/4/2010 6:49:35 PM

AngryOldMan
Suspended
655 Posts
user info
edit post

Just learn ruby so you don't have to think about this shit.

2/4/2010 6:51:39 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

no, I'm more concerned with a more efficient / easier way to find the max value and then get the rest of the info from the table without having to run a subquery first.

2/4/2010 10:57:43 PM

KillaB
All American
1652 Posts
user info
edit post

My SQL is pretty mediocre, but my understanding is that since you can't do the max() function in the where clause, there's no better way to do this than a subquery. We use effective date a lot at the company I work for and while this is a drawback, the tradeoff of having some historical data and being able to follow the flow easily for a given item, is well worth the slightly higher transaction cost.

Someone please feel free to correct me if I'm way off base here.

2/5/2010 7:29:52 AM

Wolfmarsh
What?
5975 Posts
user info
edit post

This is a tough one.

There is a way to do it with joins to eliminate the subquery, but have you actually looked at the performance of this?

Subselects can actually outperform joins in some situations.

2/5/2010 9:51:27 AM

disco_stu
All American
7436 Posts
user info
edit post

I am an idiot and cannot determine what you're trying to do. Nor does your resultset above make sense.

You want to feed it a date, determine what the highest effective date is in your table, and do what?

Do you want to get the record that has the highest effective date that is less than the date that you give? What does end date have to do with this?

2/5/2010 10:06:44 AM

aaronburro
Sup, B
53065 Posts
user info
edit post

yes, I want the record that has the highest effective date that is less than the date given, but end date must be greater than the date given, too.

I amended the result set above to be 2,4,6 as opposed to 2,3,6, btw. Overall, I'm trying to see if there is an easier way to eliminate the subquery, but apparently there is not.

2/6/2010 4:34:20 PM

disco_stu
All American
7436 Posts
user info
edit post

That's what I don't get.

If you want a record that has the highest date, why are you getting multiple records back? 2, 3, and 6 have different dates (with the highest being 6).

2/8/2010 4:40:27 PM

FroshKiller
All American
51911 Posts
user info
edit post

i basically didn't read this thread but can i just say 30-day indices

peace

2/8/2010 4:43:08 PM

1985
All American
2175 Posts
user info
edit post

don't use the coalesce on a static number. assuming last date is always in the past, use getdate() + 1, then those Y10K guys will be happy.

disco_stu I think his second example is only for the subquery, then the outer query would find a max on his second example

also, if your effective dates aren't unique for facility and charactarization, your query is going to return multiple results, im assuming this is ok?

[Edited on February 8, 2010 at 7:48 PM. Reason : .]

[Edited on February 8, 2010 at 7:49 PM. Reason : .]

[Edited on February 8, 2010 at 7:50 PM. Reason : .]

2/8/2010 7:36:06 PM

aaronburro
Sup, B
53065 Posts
user info
edit post

nah, (2,4,6) gives what I want for the whole query. I'm looking for Max(EffectiveDate (Facility,Characterization)), if that makes any sense so I can find the revision. There should be in the result set, at most, one record for each Facility/Characterization pair that exists in the table.

2/8/2010 8:18:43 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

I got queries that do exactly what you want, but wasnt able to do so effectively without subqueries.

Thier performance is comparable to doing it with joins, just use the subquery and be done with it.

2/8/2010 9:09:55 PM

KillaB
All American
1652 Posts
user info
edit post

Agree with the above. Plus if indexed properly, the overhead of the subquery is somewhat negated.

2/8/2010 11:42:41 PM

1985
All American
2175 Posts
user info
edit post

I've got a question:

Ive got a table that looks something like :

Quote :
"
 ID week  value
-- ---- -----
1 2 12
1 2 7
2 8 5
5 8 2
5 8 10

"


and I want to remove the rows with the same id and week that dont contain the maximal value

for example, what I want to remain is:


Quote :
"
 ID week  value
-- ---- -----
1 2 12
2 8 5
5 8 10

"

2/17/2010 1:03:59 PM

BigMan157
no u
103354 Posts
user info
edit post

make a temporary table
SELECT id, week, MAX(value) FROM table GROUP BY id
insert into temporary table
truncate initial table
copy temp table to initial table

i'm sure there's a much simpler way than that though

2/17/2010 1:25:11 PM

FroshKiller
All American
51911 Posts
user info
edit post

Do you honestly want to delete the records, or do you just want that output?

2/17/2010 1:51:49 PM

1985
All American
2175 Posts
user info
edit post

I want to delete them.

2/17/2010 1:54:12 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

Does this table have an identity column to it, or is that all the data that is there?

2/17/2010 1:57:57 PM

1985
All American
2175 Posts
user info
edit post

It does have an identity column

2/17/2010 2:02:23 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

Whats the name of the column and ill give you the sql.

2/17/2010 2:03:15 PM

1985
All American
2175 Posts
user info
edit post

HSID

2/17/2010 2:10:08 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

Here is my SQL, including all of my test sql to make sure it worked:

--Create test table
CREATE TABLE [dbo].[1985Data](
[HSID] [int] IDENTITY(1,1) NOT NULL,
[ID] [int],
[week] [int],
[value] [int]
)

--Clear my test table
Delete From [1985Data]

--Add test data
Insert Into [1985Data] (ID, week, value) VALUES (1, 2, 12)
Insert Into [1985Data] (ID, week, value) VALUES (1, 2, 7)
Insert Into [1985Data] (ID, week, value) VALUES (2, 8, 5)
Insert Into [1985Data] (ID, week, value) VALUES (5, 8, 2)
Insert Into [1985Data] (ID, week, value) VALUES (5, 8, 10)

--Actual delete statement
Delete From [1985Data] Where HSID Not In
(
Select HSID From [1985Data]
Where value = (Select MAX(value) from [1985Data] as D2 where D2.id=[1985Data].ID)
)

--Test output
Select * From [1985Data]

2/17/2010 2:18:28 PM

1985
All American
2175 Posts
user info
edit post

that looks like it should work, thanks. my table is ~ 50 million records, and the duplicates are probably .05% of that so I was trying to approach it by subquerying the records that should be deleted rather than the ones that shouldn't. I don't know much about optimization, would that even make a difference?

2/17/2010 3:30:11 PM

FroshKiller
All American
51911 Posts
user info
edit post

jesus christ dude

2/17/2010 3:34:30 PM

1985
All American
2175 Posts
user info
edit post

- Ya, i know.

2/17/2010 3:46:59 PM

Wolfmarsh
What?
5975 Posts
user info
edit post

It wont make that much of a difference. Proper indexing would matter more.

I've had a lot of success using the tuning wizard in the past:

http://msdn.microsoft.com/en-us/library/ms979195.aspx#scalenethowto03_topic5

There may be a more current article, but thats what I have in my favorites.

2/17/2010 3:51:23 PM

1985
All American
2175 Posts
user info
edit post

Thanks a bunch, i appreciate it.

2/17/2010 4:00:16 PM

 Message Boards » Tech Talk » ]More SQL questions! Page [1]  
go to top | |
Admin Options : move topic | lock topic

© 2024 by The Wolf Web - All Rights Reserved.
The material located at this site is not endorsed, sponsored or provided by or on behalf of North Carolina State University.
Powered by CrazyWeb v2.39 - our disclaimer.