4

TempAllAddresses次の列で呼び出されるテーブルがあります- ID、、、。新しいテーブルに、、およびを入力したいと考えています。TempAllAddresses テーブル内に、このアドレスのようなアドレスの後にワイルドカードが続くレコードがいくつあるかを表す必要があります。それが意味をなさない場合は、ここに説明する例があります-次のようなレコードがあるとしましょう:AddressStateAddressStateCountCount

ID      Address      State
12345   13 Phoenix   NY

AddressCount私がしたいことは、 の 13 フェニックス、 のAddressNY State、および州として NY を持ち、 '13 Phoenix%' のようなアドレスを持つテーブル内のレコードの数を持つという名前の新しいテーブルに新しいレコードを挿入することですCount。_

TempAllAddresses 自体の内部結合でこれを達成したいと考えています。これは私が試したものですが、探しているものを達成していないようです:

SELECT t1.Address, t1.State, COUNT(t2.address) As NumEntities
FROM TempAllAddresses t1
INNER JOIN TempAllAddresses t2
 ON t1.state = t2.state
 AND T2.Address LIKE t1.address + '%'
GROUP BY t1.State, t1.Address

ただし、カウントは間違いなくオフです。" " を実行するのと同じはずSELECT COUNT(*) FROM TempAllAddresses WHERE State=thisRecordsState and Address LIKE thisRecordsAddress + '%'です。どうすればこれを達成できますか? 私は何を間違っていますか?

編集:

カウントは次のようにずれているようです - 上記のようなレコードがあり、他に 2 つのレコードがあり、ニューヨーク州もあり、住所が「13 フェニックス ロード」と「13 フェニックス」であるとします。 Rd」の場合、次のようなレコードをファイナル テーブルに入れたいと考えています。

13 Phoenix    NY    3

代わりに、私は得ているようです:

13 Phoenix    NY    9

ここで何が起こっているのかよくわかりません...ある種のデカルト積ですか?順列…?誰でもこれを説明できますか?

編集2: 誤解されているように見えるので、さらに編集します(そして本当に解決策が必要です:()...これは、私が探しているものを達成する相関サブセレクトを使用したクエリです。同じことをしたい副選択ではなく、テーブル自体の内部結合を使用します。

SELECT Address, State, 
    (SELECT Count(*)
    FROM TempAllAddresses innerQry 
    WHERE innerQry.address LIKE outerQry.address + '%' 
        AND innerQry.state = outerQry.state) As NumEntities
FROM TempAllAddresses outerQry

基本的に、各レコードについて、同じ状態と、このアドレスで始まるアドレスを持つテーブル内のレコードの数を取得したい (または等しい... このアドレスをカウントの一部として含めたい)。

4

7 に答える 7

1

1 つは CROSS APPLY を使用し、もう 1 つは元々望んでいたように INNER JOIN を使用します。これが役立つことを願っています。:)

DECLARE @TempAllAddresses TABLE
(
    ID INT PRIMARY KEY IDENTITY(1, 1) NOT NULL
    , [Address] VARCHAR(250) NOT NULL
    , [State] CHAR(2) NOT NULL
)

INSERT INTO @TempAllAddresses
VALUES ('13 Phoenix', 'NY')
        , ('13 Phoenix St', 'NY')
        , ('13 Phoenix Street', 'NY')
        , ('1845 Test', 'TN')
        , ('1337 Street', 'WA')
        , ('1845 T', 'TN')

SELECT
    TempAddresses.ID
    , TempAddresses.[Address]
    , TempAddresses.[State]
    , TempAddressesCounted.AddressCount
FROM @TempAllAddresses TempAddresses
CROSS APPLY
(
    SELECT
        COUNT(*) AS AddressCount
    FROM @TempAllAddresses TempAddressesApply
    WHERE TempAddressesApply.[Address] LIKE (TempAddresses.[Address] + '%')
        AND TempAddressesApply.[State] = TempAddresses.[State]
) TempAddressesCounted

SELECT
    TempAddresses.ID
    , TempAddresses.[Address]
    , TempAddresses.[State]
    , COUNT(*) AS AddressCount
FROM @TempAllAddresses TempAddresses
INNER JOIN @TempAllAddresses TempAddressesJoin
    ON TempAddressesJoin.[Address] LIKE (TempAddresses.[Address] + '%')
            AND TempAddressesJoin.[State] = TempAddresses.[State]
GROUP BY TempAddresses.ID
    , TempAddresses.[Address]
    , TempAddresses.[State]
于 2010-12-31T22:18:58.860 に答える
0

ネストされたGroupBy:

  • サブクエリは、個別のアドレスごとに最短のアドレスを検索します。
  • これは大文字と小文字の区別を考慮していません。
  • 次に、これらのアドレスの各バージョンがカウントされます。

SQL:

SELECT Address, State, count(1) As NumEntities
FROM ( 
    SELECT min(t1.Address) as Address, t1.State
    FROM TempAllAddresses t1
    INNER JOIN TempAllAddresses t2
     ON t1.state = t2.state
     AND T2.Address LIKE t1.address + '%'
    GROUP BY t1.State, t2.Address
) GROUP By State, Address
于 2010-12-14T10:11:27.807 に答える
0

分析機能を試したことがありますか - 多くの場合、分析機能が最も簡単な解決策です。私はあなたのテーブル構造に精通していませんが、次のようなものでなければなりません:

SELECT t1.Address, t1.State, 
COUNT(t2.address) OVER (PARTITION BY t2.state) As NumEntities
FROM TempAllAddresses t1
INNER JOIN TempAllAddresses t2
ON t1.state = t2.state
AND T2.Address LIKE t1.address + '%'
GROUP BY t1.State, t1.Address

句を追加ORDER BYすることもできます。説明については、 Oracle の FAQOVERを参照してください。

于 2010-12-31T15:39:50.410 に答える
0

編集:[古いものを切り取る]

これを試して:

SELECT t1.Address, t1.State, COUNT(distinct t2.id) As NumEntities
FROM TempAllAddresses t1
INNER JOIN TempAllAddresses t2
 ON t1.state = t2.state
 AND T2.Address LIKE t1.address + '%'
GROUP BY t1.State, t1.Address
于 2010-12-13T09:57:29.637 に答える
0

クエリ A:

SELECT t1.Address, t1.State, COUNT(t2.address) As NumEntities
FROM TempAllAddresses t1
INNER JOIN TempAllAddresses t2
 ON t1.state = t2.state
 AND T2.Address LIKE t1.address + '%'
GROUP BY t1.State, t1.Address

と同等ではありません

クエリ B:

SELECT Address, State, 
    (SELECT Count(*)
    FROM TempAllAddresses innerQry 
    WHERE innerQry.address LIKE outerQry.address + '%' 
        AND innerQry.state = outerQry.state) As NumEntities
FROM TempAllAddresses outerQry

B は元のテーブルの行ごとに 1 行を生成するため ( TempAllAddresses)、A は元のテーブルの同じ状態とアドレスを持つ行をグループ化します。これを解決するには、GROUP BY t1.ID, t1.State, t1.Address代わりに.

于 2010-12-13T10:55:45.757 に答える
0

まったく同じアドレスの行が複数ある場合、二重カウントが発生します。

試す:

SELECT t1.Address, t1.State, COUNT(t2.address) As NumEntities
FROM (select distinct Address, State from TempAllAddresses) t1
INNER JOIN TempAllAddresses t2
 ON t1.state = t2.state
 AND T2.Address LIKE t1.address + '%'
GROUP BY t1.State, t1.Address
于 2010-12-13T13:50:43.790 に答える
0

代わりにこれを試してください:

SELECT Orig_Address, State, COUNT(Similar_Address)
From
(
  SELECT t1.Address Orig_Address, 
         t1.State   State, 
         t2.address Similar_Address
    FROM TempAllAddresses t1
   INNER JOIN TempAllAddresses t2
      ON t1.state = t2.state
     AND T2.Address LIKE t1.address + '%'
     AND t1.address <> t2.address
)
GROUP BY State, Orig_Address

編集: @Spiny Norman が言ったように、アドレスをそれ自体と比較したくないので、t1.address と t2.address の違いを含めるのを忘れました。

HTH

于 2010-12-13T09:40:15.757 に答える