Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
julianfraser
Starting Member
19 Posts |
Posted - 2005-04-11 : 14:49:14
|
| I'm having real trouble getting this query to work. Basically there is a table called 'LM001_property_listing' which contains a column called 'listing_start'. I want to only select the top 1 record for each 'listing_start' column, ie. selectig only 1 record for each propertyID, but making sure it is the most recent 'listing_start' date. I have done this in the second query, but then the case statement does not work. Is is the result of the case statement that I need, not necessarily the most recent 'listing_start' date.Any ideas?Thanks,Julian.SELECT p.propertyID, p.title, p.address1, p.address2, p.town, p.postcode, p.price, ppt.price_term, pt.property_term, pty.property_type, lt.listing_type, ss.sale_status, CASE WHEN pl.listing_end IS NULL AND pl.listing_start IS NOT NULL THEN 'NEVER' WHEN pl.listing_end < GETDATE() AND pl.listing_end IS NOT NULL THEN 'EXPIRED' WHEN pl.listing_end IS NULL AND pl.listing_start IS NULL THEN 'UNPAID' ELSE CONVERT(varchar(36), pl.listing_end, 9) END AS 'expires' FROM LM001_property p LEFT JOIN LM001_property_price_term ppt ON ppt.price_termID = p.price_termID LEFT JOIN LM001_property_term pt ON pt.property_termID = p.property_termID LEFT JOIN LM001_property_type pty ON pty.property_typeID = p.property_typeID LEFT JOIN LM001_listing_type lt ON lt.listing_typeID = p.listing_typeID LEFT JOIN LM001_sale_status ss ON ss.sale_statusID = p.sale_statusID LEFT JOIN LM001_property_listing pl ON pl.propertyID = p.propertyID WHERE p.userID = 300001 ORDER BY lt.listing_typeSELECT p.propertyID, p.title, p.address1, p.address2, p.town, p.postcode, p.price, ppt.price_term, pt.property_term, pty.property_type, lt.listing_type, ss.sale_status, (SELECT MAX(pl.listing_start) FROM LM001_property_listing pl WHERE pl.propertyID = p.propertyID) AS 'starts' FROM LM001_property p LEFT JOIN LM001_property_price_term ppt ON ppt.price_termID = p.price_termID LEFT JOIN LM001_property_term pt ON pt.property_termID = p.property_termID LEFT JOIN LM001_property_type pty ON pty.property_typeID = p.property_typeID LEFT JOIN LM001_listing_type lt ON lt.listing_typeID = p.listing_typeID LEFT JOIN LM001_sale_status ss ON ss.sale_statusID = p.sale_statusID WHERE p.userID = 300001 ORDER BY lt.listing_type |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-04-11 : 15:12:42
|
will this do it?--replace this:--LEFT JOIN LM001_property_listing pl ON pl.propertyID = p.propertyID --with thisLEFT JOIN ( --derived table of most recent listing_start records by propertyid Select propertyid, max(listing_start) listing_start From LM001_property_listing a JOIN LM001_property b ON a.propertyID = b.PropertyID Where p.userid = 300001 Group by propertyid ) pl ON pl.propertyID = p.propertyID EDIT: Hold on that's not quite right. You also need listing_end. just a sec...I'm not sure if "top 1" works with a correlated sub-query but try this: (it may be too slow too, let me know)--replace this:--LEFT JOIN LM001_property_listing pl ON pl.propertyID = p.propertyID --with thisLEFT JOIN ( --derived table of most recent listing_start records by propertyid Select top 1 listing_start, listing_end From LM001_property_listing a Where propertyID = p.PropertyID order by listing_start desc ) pl ON pl.propertyID = p.propertyID Be One with the OptimizerTG |
 |
|
|
julianfraser
Starting Member
19 Posts |
Posted - 2005-04-12 : 05:12:58
|
| It didn't like it, doesn't like the reference to the table outside of the subquery. Gave this error.Server: Msg 107, Level 16, State 2, Line 1The column prefix 'p' does not match with a table name or alias name used in the query.SELECT p.propertyID, p.title, p.address1, p.address2, p.town, p.postcode, p.price, ppt.price_term, pt.property_term, pty.property_type, lt.listing_type, ss.sale_status FROM LM001_property p LEFT JOIN LM001_property_price_term ppt ON ppt.price_termID = p.price_termID LEFT JOIN LM001_property_term pt ON pt.property_termID = p.property_termID LEFT JOIN LM001_property_type pty ON pty.property_typeID = p.property_typeID LEFT JOIN LM001_listing_type lt ON lt.listing_typeID = p.listing_typeID LEFT JOIN LM001_sale_status ss ON ss.sale_statusID = p.sale_statusID LEFT JOIN ( Select top 1 listing_start, listing_end From LM001_property_listing a Where a.propertyID = p.PropertyID order by listing_start desc ) pl ON pl.propertyID = p.propertyID WHERE p.userID = 300001 ORDER BY lt.listing_type |
 |
|
|
julianfraser
Starting Member
19 Posts |
Posted - 2005-04-12 : 06:40:31
|
| I meant this one... still returned this though...Server: Msg 107, Level 16, State 2, Line 1The column prefix 'p' does not match with a table name or alias name used in the query.SELECT p.propertyID, p.title, p.address1, p.address2, p.town, p.postcode, p.price, ppt.price_term, pt.property_term, pty.property_type, lt.listing_type, ss.sale_status,CASEWHEN pl.listing_end IS NULL AND pl.listing_start IS NOT NULL THEN 'NEVER'WHEN pl.listing_end < GETDATE() AND pl.listing_end IS NOT NULL THEN 'EXPIRED'WHEN pl.listing_end IS NULL AND pl.listing_start IS NULL THEN 'UNPAID'ELSE CONVERT(varchar(36), pl.listing_end, 9)END AS 'expires'FROM LM001_property p LEFT JOIN LM001_property_price_term ppt ON ppt.price_termID = p.price_termIDLEFT JOIN LM001_property_term pt ON pt.property_termID = p.property_termIDLEFT JOIN LM001_property_type pty ON pty.property_typeID = p.property_typeIDLEFT JOIN LM001_listing_type lt ON lt.listing_typeID = p.listing_typeIDLEFT JOIN LM001_sale_status ss ON ss.sale_statusID = p.sale_statusIDLEFT JOIN ( Select top 1 listing_start, listing_end From LM001_property_listing a Where a.propertyID = p.PropertyID order by listing_start desc ) pl ON pl.propertyID = p.propertyID WHERE p.userID = 300001ORDER BY lt.listing_type |
 |
|
|
mwjdavidson
Aged Yak Warrior
735 Posts |
Posted - 2005-04-12 : 07:07:42
|
Not exactly sure what you want, but this should constrain the listings to just the most recent ones:SELECT p.propertyID, p.title, p.address1, p.address2, p.town, p.postcode, p.price, ppt.price_term, pt.property_term, pty.property_type, lt.listing_type, ss.sale_status, pl.listing_start as start, CASEWHEN pl.listing_end IS NULL AND pl.listing_start IS NOT NULL THEN 'NEVER'WHEN pl.listing_end < GETDATE() AND pl.listing_end IS NOT NULL THEN 'EXPIRED'WHEN pl.listing_end IS NULL AND pl.listing_start IS NULL THEN 'UNPAID'ELSE CONVERT(varchar(36), pl.listing_end, 9)END AS 'expires'FROM LM001_property p LEFT JOIN LM001_property_price_term ppt ON ppt.price_termID = p.price_termIDLEFT JOIN LM001_property_term pt ON pt.property_termID = p.property_termIDLEFT JOIN LM001_property_type pty ON pty.property_typeID = p.property_typeIDLEFT JOIN LM001_listing_type lt ON lt.listing_typeID = p.listing_typeIDLEFT JOIN LM001_sale_status ss ON ss.sale_statusID = p.sale_statusIDLEFT JOIN LM001_property_listing pl JOIN ( SELECT pl2.propertyID, MAX(pl2.listing_start) AS listing_start FROM dbo.LM001_property_listing pl2 GROUP BY pl2.propertyID) AS pl2ON pl.propertyID = pl2.propertyIDAND pl.listing_start = pl2.listing_startON pl.propertyID = p.propertyID WHERE p.userID = 300001ORDER BY lt.listing_type Mark |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-04-12 : 08:24:31
|
Mark's solution is the same as my first attempt. It doesn't include both the listing_end and listing_start for the max listing_start by propertyid.this should do it: (he said hopefully)--with thisLEFT JOIN ( --derived table of most recent listing records by propertyid Select a.PropertyID, a.Listing_start, max(a.Listing_end) listing_end From From LM001_property_listing a JOIN (--another derived table to get the latest listing_start for each propertyid Select PropertyID, max(listing_start) listing_start From LM001_property_listing group by propertyID ) b ON a.propertyID = b.PropertyID and a.listing_start = b.listing_start Group by a.PropertyID, a.Listing_start ) pl ON pl.propertyID = p.propertyID The max(Listing_end) and group by is there in case there are multiple listings for the same propertyid/listing_start combinationBe One with the OptimizerTG |
 |
|
|
mwjdavidson
Aged Yak Warrior
735 Posts |
Posted - 2005-04-12 : 11:02:06
|
| Hi TGThe difference was that, by just constraining the join to LM001_property_listing with a join to the derived table containing the aggregate function, you can then just add listing_start and listing_end from LM001_property_listing to your select statement (or plug them into the case statement).Mark |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-04-12 : 11:07:58
|
| Hi Mark,Now that you say that, I noticed the additional JOIN criteria (AND pl.listing_start = pl2.listing_start).That would do it alright. The only possible problem would be if there are multiple listing records for the same propertyid and same listing_start. That would give dupe records in the result. My last attempt should deal with that but hopefully Julian's data doesn't have that situation in which case your solution would be great.Be One with the OptimizerTG |
 |
|
|
mwjdavidson
Aged Yak Warrior
735 Posts |
Posted - 2005-04-12 : 11:52:22
|
| You're quite right TG, I was making a wee assumption there!Anyway, let's hope Julian manages to make some use of our efforts. He seems to have gone a bit quiet!Mark |
 |
|
|
julianfraser
Starting Member
19 Posts |
Posted - 2005-04-12 : 13:29:36
|
| I'm still here... had my head buried in code all day. Am trying your solutions now. Thanks for all your help.Julian. |
 |
|
|
julianfraser
Starting Member
19 Posts |
Posted - 2005-04-13 : 08:52:14
|
| TG and Mark, The new query worked great, thanks for that... i'd been scratching my head for hours.Cheers for the help,Julian. |
 |
|
|
|
|
|
|
|