Showing posts with label blocked. Show all posts
Showing posts with label blocked. Show all posts

Monday, March 26, 2012

Help finding the top 3 zipcodes within the top 5 counties

I need to show data for the top 3 zipcodes for EACH of the top 5
counties. I feel totally blocked on how to make this work properly.
Here is my code - anything you can suggest will be greatly appreciated:

SET ROWCOUNT 5
DECLARE @.tblTopMarkets TABLE (StateCD CHAR(2), CountyCD CHAR(3))
INSERT INTO @.tblTopMarkets
select
S.StateCD,
S.CountyCD
FROM DAPSummary_By_County S
WHERE S.SaleMnYear > '01/01/2004'
GROUP BY S.StateCD, S.CountyCD Order By Sum(S.Nbr_MTG) DESC
-- the above works fine but next select produces only 3 rows;
-- I need 3 times 5 rows (how to effect a "loop")
SELECT TOP 3-- zips in a county
D.StateCD,
D.CountyCD,
D.Zip,
"Nbr_Mtg"= Sum(Nbr_MTG)
FROM @.tblTopMarkets T
LEFT JOIN GovtFHADetails D
ON T.StateCD = D.StateCD AND T.CountyCD = D.CountyCD

WHERE D.SaleMnYear > '01/01/2004'
GROUP BY D.StateCD, D.CountyCD, D.Zip
Order By Sum(Nbr_MTG) DESCJJA (johna@.cbmiweb.com) writes:
> I need to show data for the top 3 zipcodes for EACH of the top 5
> counties. I feel totally blocked on how to make this work properly.
> Here is my code - anything you can suggest will be greatly appreciated:
> SET ROWCOUNT 5
> DECLARE @.tblTopMarkets TABLE (StateCD CHAR(2), CountyCD CHAR(3))
> INSERT INTO @.tblTopMarkets
> select
> S.StateCD,
> S.CountyCD
> FROM DAPSummary_By_County S
> WHERE S.SaleMnYear > '01/01/2004'
> GROUP BY S.StateCD, S.CountyCD Order By Sum(S.Nbr_MTG) DESC
> -- the above works fine but next select produces only 3 rows;
> -- I need 3 times 5 rows (how to effect a "loop")
> SELECT TOP 3 -- zips in a county
> D.StateCD,
> D.CountyCD,
> D.Zip,
> "Nbr_Mtg" = Sum(Nbr_MTG)
> FROM @.tblTopMarkets T
> LEFT JOIN GovtFHADetails D
> ON T.StateCD = D.StateCD AND T.CountyCD = D.CountyCD
> WHERE D.SaleMnYear > '01/01/2004'
> GROUP BY D.StateCD, D.CountyCD, D.Zip
> Order By Sum(Nbr_MTG) DESC

This is a whole nicer to do in SQL 2005, where you have ranking functions,
so you can rank the rows in the query.

But now we are on SQL 2000. Being a bit tired tonight, I didn't come up
with anything better than:

SET ROWCOUNT 0 -- don't forget to reset!

CREATE TABLE #temp (ident int IDENTITY,
stateCD ...
countyCD ...
zip ...
Nbr_mtg ...)
INSERT #temp (stateCD, coutnyCD, zip, nbr_mtg)
SELECT D.StateCD, D.CountyCD, D.Zip, Sum(Nbr_MTG)
FROM @.tblTopMarkets T
LEFT JOIN GovtFHADetails D
ON T.StateCD = D.StateCD AND T.CountyCD = D.CountyCD

WHERE D.SaleMnYear > '01/01/2004'
GROUP BY D.StateCD, D.CountyCD, D.Zip
GROUP BY D.StateCD, D.CountyCD, D.Zip, Sum(Nbr_MTG) DESC

SELECT a.stateCD, a.countyCD, a.zip, a.nbr_mtg
FROM #temp a
JOIN (SELECT stateCD, countyCD, zip, ident = min(ident)
FROM #temp
GROUP BY stateCD, countyCD, zip= AS b
ON a.stateCD = b.stateCD
AND a.countyCD = b.countyCD
AND a.zip = b.zip
AND a.ident < b.ident +3
ORDER BY a.stateCD, a.countyCD, a.zip, a.nbr_mtg

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Thanks very much for your suggestion. I couldn't get it to work as it
was but I tried to take the idea and apply it. Came up with a new
version (same objective) but I am still stuck. I cannot get it to peel
off the top 3 rows in each county. I get 393 rows in the final
resultset where I really want only 15 rows (5 counties times top 3
zipcodes in each county). I am beginning to think I need a cursor.
Here's my SQL:

SET ROWCOUNT 5
DECLARE @.tblTemp TABLE (
ident int IDENTITY,
StateCD CHAR(2),
CountyCD CHAR(3),
ZipCHAR(5),
Nbr_MtgINT)
DECLARE @.tblTopMarkets TABLE (StateCD CHAR(2), CountyCD CHAR(3))
INSERT INTO @.tblTopMarkets
SELECT S.StateCD,
S.CountyCD
FROM DAPSummary_By_County S
WHERE S.SaleMnYear > '01/01/2004'
GROUP BY S.StateCD, S.CountyCD Order By Sum(S.Nbr_MTG) DESC

SET ROWCOUNT 0
INSERT INTO @.tblTemp (StateCD, CountyCD, Zip, Nbr_Mtg)
SELECT D.StateCD,
D.CountyCD,
D.Zip,
"Nbr_Mtg"= Sum(Nbr_MTG)
FROM @.tblTopMarkets T
LEFT JOIN GovtFHADetails D
ON T.StateCD = D.StateCD AND T.CountyCD = D.CountyCD
WHERE D.SaleMnYear > '01/01/2004' AND D.NonPro IS NOT NULL
GROUP BY D.StateCD, D.CountyCD, D.Zip
Order By Sum(Nbr_MTG) DESC
DECLARE @.tblByCounty TABLE (
ident int IDENTITY,
StateCD CHAR(2),
CountyCD CHAR(3),
ZipCHAR(5),
Nbr_MtgINT,
NationalRank INT)
INSERT INTO @.tblByCounty (StateCD, CountyCD, Zip, Nbr_Mtg,
NationalRank)
SELECT A.StateCD, A.CountyCD, A.Zip, A.Nbr_Mtg, A.ident AS NationalRank
FROM @.tblTemp A -- this set ranks by biggest zipcodes WITHIN
each county
ORDER BY A.StateCD, A.CountyCD, A.Nbr_MTG DESC, A.Zip
SELECT A.StateCD, A.CountyCD, A.Zip, A.Nbr_Mtg, A.ident, A.NationalRank
FROM @.tblByCounty A -- this set ranks by biggest zipcodes WITHIN
each county
ORDER BY A.StateCD, A.CountyCD, A.Nbr_MTG DESC, A.Zip

SELECT A.ident, B.ident, A.StateCD, A.CountyCD, A.Zip, A.Nbr_Mtg,
A.NationalRank
FROM @.tblByCounty A
JOIN
(SELECT Min(X.ident) AS ident, X.StateCD, X.CountyCD, X.Zip,
X.Nbr_Mtg, X.NationalRank
FROM @.tblByCounty X
GROUP BY X.StateCD, X.CountyCD, X.Zip, X.Nbr_Mtg, X.NationalRank
) AS B
ON A.StateCD = B.StateCD
AND A.CountyCD = B.CountyCD
AND A.Zip = B.Zip
AND A.ident = B.ident
WHERE A.ident < B.ident + 3
ORDER BY A.StateCD, A.CountyCD, A.Nbr_Mtg DESC|||it would be a snap in 2005, yet it's quite doable in 2000

create table #zips(id int, region char(2), zip int, sum_sales int)
insert into #zips values(1, 'IL', 60563, 12)
insert into #zips values(2, 'IL', 60564, 13)
-- a tie deliberately
insert into #zips values(3, 'IL', 60565, 14)
insert into #zips values(4, 'IL', 60566, 14)
insert into #zips values(5, 'IL', 60567, 14)
insert into #zips values(6, 'IL', 60569, 14)

insert into #zips values(7, 'WI', 53718, 12)
insert into #zips values(8, 'WI', 53711, 1)
insert into #zips values(9, 'WI', 53712, 4)
insert into #zips values(10, 'WI', 53715, 7)
insert into #zips values(11, 'WI', 53714, 5)
insert into #zips values(12, 'WI', 53712, 3)

select * from #zips z
where (select count(*) from #zips z1 where z.region=z1.region
and ((z.sum_sales<z1.sum_sales)or(z.sum_sales=z1.sum_sales and
z.id<=z1.id))) <= 3

id region zip sum_sales
---- -- ---- ----
4 IL 60566 14
5 IL 60567 14
6 IL 60569 14
7 WI 53718 12
10 WI 53715 7
11 WI 53714 5

(6 row(s) affected)

drop table #zips|||You are brilliant! Thank you so much for your help! I adapted your
approach and example to my data and it works beautifully. Here is my
final SQL:

SET ROWCOUNT 5
DECLARE @.tblTemp TABLE (
ident int IDENTITY,
StateCD CHAR(2),
CountyCD CHAR(3),
ZipCHAR(5),
Nbr_MtgINT)
DECLARE @.tblTopMarkets TABLE (StateCD CHAR(2), CountyCD CHAR(3))
INSERT INTO @.tblTopMarkets
SELECT S.StateCD,
S.CountyCD
FROM DAPSummary_By_County S
WHERE S.SaleMnYear > '01/01/2004'
GROUP BY S.StateCD, S.CountyCD Order By Sum(S.Nbr_MTG) DESC

SET ROWCOUNT 0
INSERT INTO @.tblTemp (StateCD, CountyCD, Zip, Nbr_Mtg)
SELECT D.StateCD,
D.CountyCD,
D.Zip,
"Nbr_Mtg"= Sum(Nbr_MTG)
FROM @.tblTopMarkets T
LEFT JOIN GovtFHADetails D
ON T.StateCD = D.StateCD AND T.CountyCD = D.CountyCD
WHERE D.SaleMnYear > '01/01/2004' AND D.NonPro IS NOT NULL
GROUP BY D.StateCD, D.CountyCD, D.Zip
Order By Sum(Nbr_MTG) DESC
DECLARE @.tblByCounty TABLE (
ident int IDENTITY,
StateCD CHAR(2),
CountyCD CHAR(3),
ZipCHAR(5),
Nbr_MtgINT,
NationalRank INT)
INSERT INTO @.tblByCounty (StateCD, CountyCD, Zip, Nbr_Mtg,
NationalRank)
SELECT A.StateCD, A.CountyCD, A.Zip, A.Nbr_Mtg, A.ident AS NationalRank
FROM @.tblTemp A
ORDER BY A.StateCD, A.CountyCD, A.Nbr_MTG DESC, A.Zip

SELECT A.ident, A.StateCD, A.CountyCD, A.Zip, A.Nbr_Mtg, A.NationalRank
FROM @.tblByCounty A
WHERE
(SELECT COUNT(*)
FROM @.tblByCounty X
WHERE X.StateCD = A.StateCD AND X.CountyCD = A.CountyCD
AND
(
(A.Nbr_Mtg < X.Nbr_Mtg)
OR
( A.Nbr_Mtg = X.Nbr_Mtg AND A.ident <= X.ident)
)
) <= 3
ORDER BY A.StateCD, A.CountyCD, A.Nbr_Mtg DESC

Monday, March 19, 2012

HELP : Remote query from 2005 to 2000 returns wrong recordset when

Hi there
I came across this bug and could not find a solution, and I'm blocked.
Can anyone help ?
I have a table with TABLE CONSTRAINT, located at a SQL 2000 (SP3 or
SP4) server.
When I make a remote query from a (linked) SQL 2005 server (SP1 or
SP2), the returned recordset is totally wrong (rows are missing).
The problem does not occur between two SQL 2000, nor between two SQL
2005.Eric,
Can you define the condition of the missing rows better? That might give a
clue.
One suggestion is to compare the collations of the SQL 2000 server and
database with the collations of the SQL 2005 server and database. If that
is a problem, you might be able to resolve it with a COLLATE clause in the
query.
RLF
<EricBello@.eurofins.com> wrote in message
news:9c42bd9d-8d35-4370-bcd5-293830ac27f7@.l1g2000hsa.googlegroups.com...
> Hi there
> I came across this bug and could not find a solution, and I'm blocked.
> Can anyone help ?
> I have a table with TABLE CONSTRAINT, located at a SQL 2000 (SP3 or
> SP4) server.
> When I make a remote query from a (linked) SQL 2005 server (SP1 or
> SP2), the returned recordset is totally wrong (rows are missing).
> The problem does not occur between two SQL 2000, nor between two SQL
> 2005.
>|||Here is the script to reproduce the problem
At SQL 2000 side (SP3 or SP4) :
--cleanup
--DROP TABLE MyPackagesTranslations
--DROP TABLE MyPackages
GO
USE pubs
GO
SET ANSI_NULLS, QUOTED_IDENTIFIER ON
GO
-- Create the table MyPackages,
CREATE TABLE [dbo].[MyPackages](
[packageIncId] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[packageSqlId] [smallint] NOT NULL CONSTRAINT
[DF_MyPackages_packageSqlId] DEFAULT (1121),
[packageName] [nvarchar](60) NULL,
[isDeleted] [bit] NOT NULL CONSTRAINT
[DF_MyPackages_isDeleted_Default] DEFAULT (0x00),
CONSTRAINT [PK_MyPackages] PRIMARY KEY CLUSTERED
(
[packageIncId] ASC,
[packageSqlId] ASC
)
)
GO
-- Create linked table MyPackagesTranslations
CREATE TABLE [dbo].[MyPackagesTranslations](
[packageTranslationIncId] [int] IDENTITY(1,1) NOT FOR REPLICATION
NOT NULL,
[packageTranslationSqlId] [smallint] NOT NULL CONSTRAINT
[DF_MyPackagesTranslations_packageTranslationSqlId] DEFAULT (1121),
[packageIncId] [int] NOT NULL,
[packageSqlId] [smallint] NOT NULL,
[packageTranslationName] [nvarchar](60) NULL,
CONSTRAINT [PK_MyPackagesTranslations] PRIMARY KEY CLUSTERED
(
[packageTranslationIncId] ASC,
[packageTranslationSqlId] ASC
)
)
GO
-- ... with a foreign key between them
ALTER TABLE [dbo].[MyPackagesTranslations] WITH NOCHECK ADD CONSTRAINT
[FK_MyPackagesTranslations_MyPackages]
FOREIGN KEY([packageIncId], [packageSqlId])
REFERENCES [dbo].[MyPackages] ([packageIncId], [packageSqlId])
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[MyPackagesTranslations] CHECK CONSTRAINT
[FK_MyPackagesTranslations_MyPackages]
GO
-- Insert some data with "packageSqlId = 1"
INSERT MyPackages (packageSqlId, packageName) VALUES (1, 'Foo')
INSERT MyPackages (packageSqlId, packageName) VALUES (1, 'Bar')
INSERT MyPackages (packageSqlId, packageName) VALUES (1, 'Cat')
INSERT MyPackagesTranslations (packageIncId, packageSqlId,
packageTranslationName)
SELECT packageIncId, packageSqlId, 'Translated ' + packageName
FROM dbo.MyPackages
GO
-- Now Add a CHECK CONSTRAINT for MyPackages.packageSqlId = 1121
ALTER TABLE [dbo].[MyPackages] WITH NOCHECK ADD CONSTRAINT
[CK_MyPackages] CHECK NOT FOR REPLICATION
(([packageSqlId] = 1121))
GO
ALTER TABLE [dbo].[MyPackages] CHECK CONSTRAINT [CK_MyPackages]
GO
=> And now at SQL 2005 side (SP1 or SP2)
Execute the query :
-- Now connect to another server with SQL 2005 SP1 or SP2, and launch
the remote query
-- (first verify you have a linked server)
SELECT count(*)
from <remoteserver>.pubs.dbo.MyPackages pack
INNER JOIN <remoteserver>.pubs.dbo.MyPackagesTranslations trans
ON (pack.packageIncId=trans.packageIncId and
pack.packageSqlId=trans.packageSqlId)
where pack.isDeleted=0x0
--=> returns "0" (KO) : should be "3"|||The collations are the same.
I really suspect a bug like the one on the optimizer that considered
some constraints trustworthy whereas they were "not for replication".|||I drilled down to the execution plan, and I can clearly see the
optimizer including the condition "where ...packageSqlId = 1121",
which shows it actually considers the table constraint
"trustworthy" (or sth alike) and restricts the recordset accordingly.|||The missing rows are those that don't comply with the TABLE CONSTRAINT.|||Eric,
Sorry, I really don't know. I used your repro script and get the same
results that you do.
Other things that I tried, on the SQL 2000 server create the RemoteServer
linked server pointing back to itself. Here were my results trying this:
SQLOLEDB connection: Returned 3 as desired.
SQLNCLI connection: I get the following error
OLE DB error trace [Non-interface error: Column 'packageTranslationName'
(compile-time ordinal 5) of object '"pubs"."dbo"."MyPackagesTranslations"'
was reported to have changed. The exact nature of the change is unknown].
Msg 7356, Level 16, State 1, Line 1
OLE DB provider 'SQLNCLI' supplied inconsistent metadata for a column.
Metadata information was changed at execution time.
And, no matter what I try from the SQL 2005 server, I always get 0 returned.
In addition to SQLNCLI connect, I tried to script in a SQLOLEDB connect, but
it converted to SQLNCLI. I tried creating the remote server using the SQL
Server radio button, also. No change in query result.
Is SQLNCLI at the root of the problem? I don't know enough to say.
So, I would say that you have probably found a bug that you could choose to
report to Microsoft. At least a bit of googling did not help me find an
answer.
RLF
<erbellico@.gmail.com> wrote in message
news:06af6c0c-6f36-4e3d-b671-64a27caa12d2@.s12g2000prg.googlegroups.com...
> The missing rows are those that don't comply with the TABLE CONSTRAINT.