4

我有一个名为TempAllAddresses以下列的表 - ID, Address, State. 我想用 、 和 填充一个AddressStateCountCount应该表示 TempAllAddresses 表中有多少记录具有类似此地址的地址,后跟通配符。如果这没有意义,这里有一个例子来说明 - 假设我有这样的记录:

ID      Address      State
12345   13 Phoenix   NY

我想要做的是将一条新记录插入一个名为的新表中,该表AddressCount有13 个 Phoenix 表示. _AddressStateCount

我想通过 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 条记录也有 NY,然后有“13 Phoenix Road”和“13 Phoenix”的地址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

这是两种解决方案,一种使用 CROSS APPLY,另一种使用您最初想要的 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

试试这个:

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

编辑:忘记包括 t1.address 和 t2.address 之间的区别,正如@Spiny Norman 所说,因为您可能不想将地址与自身进行比较。

高温高压

于 2010-12-13T09:40:15.757 回答
0

问题一:

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(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

您是否尝试过分析功能 - 它们通常是最简单的解决方案。我不熟悉你的表结构,但它应该是这样的:

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 BYOVER子句中添加。有关一些解释,请参阅Oracle 常见问题解答

于 2010-12-31T15:39:50.410 回答
0

嵌套分组:

  • 子查询将为每个不同的地址找到最短的地址。
  • 这不考虑区分大小写。
  • 然后计算这些地址的每个版本。

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) 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 回答