我有下表
AccountID Name
1 Foo Bar
2 Jon Dow
AccountID AddressLine City
1 123 Test RD New York
1 456 Test RD New York
2 Lombard Street San Francisco
2 Lombard Street San Francisco
对于给定的帐户ID,我想选择地址行和城市。如果帐户具有相同的AddressLine
,则应选择该AddressLine值,否则返回'Multiple'。如果帐户具有相同的City
,则应选择该城市值,否则返回“多个”。
例如,对于帐户ID 1,查询应返回
AccountID AddressLine City
1 Multiple New York
这里是SQLFiddle
以下是我的查询(不起作用)。我认为问题是分组并从子查询中选择计数
SELECT
A.AccountID,
CASE
WHEN T1.CNT = 1
THEN T1.AddressLine
ELSE 'Multiple'
END AS 'Address Line',
CASE WHEN T2.CNT = 1
THEN T2.City
ELSE 'Multiple'
END AS 'City'
FROM Accounts A
INNER JOIN
(
SELECT
ad.AccountID,
COUNT(DISTINCT(ad.AccountID)) AS CNT,
ad.AddressLine
FROM Addresses ad
GROUP BY ad.AccountID, ad.AddressLine
) T1 ON T1.AccountID = A.AccountID
INNER JOIN
(
SELECT
ad.AccountID,
COUNT(DISTINCT(ad.AccountID)) AS CNT,
ad.City
FROM Addresses ad
GROUP BY ad.AccountID, ad.City
) T2
ON T2.AccountID = A.AccountID
WHERE
a.AccountID = 1
我认为应该这样做。我使用了string_agg
函数来汇总组中的地址,因为无论如何您只想显示一个值。我放弃了仅显示单个帐户的where谓词,但是将其添加回去很简单。
string_agg
这里是另一种使用;with dist
as
(
SELECT DISTINCT
AccountID
,AddressLine
,City
FROM addresses
)
,agg
as
(
SELECT
AccountID
,COUNT(*) as AddressCount
,STRING_AGG(AddressLine, ',') as Address
,STRING_AGG(City, ',') as City
FROM dist
GROUP BY AccountID
)
select
AccountID
,CASE AddressCount
WHEN 0 THEN 'N/A'
WHEN 1 THEN Address
ELSE 'Multiple' END as Address
,CASE AddressCount
WHEN 0 THEN 'N/A'
WHEN 1 THEN City
ELSE 'Multiple' END as City
from agg
的解决方案
CROSS APPLY
这是您可以在SSMS中运行的简单示例:
SELECT
AccountID
, CASE
WHEN x.countOfDictinctAddressLine = 1
THEN x.firstAddressLine
ELSE 'Multiple'
END AS AddressLine
, City
FROM
Addresses AS source
CROSS APPLY
(
SELECT
COUNT(DISTINCT AddressLine) AS countOfDictinctAddressLine
, MIN(AddressLine) AS firstAddressLine
FROM
Addresses
WHERE
AccountID = source.AccountID
) x
GROUP BY
AccountID
, x.countOfDictinctAddressLine
, x.firstAddressLine
, City;
AccountID 1退货
DECLARE @Accounts TABLE ( AccountID INT, Name VARCHAR(50) );
INSERT INTO @Accounts ( AccountID, Name )
VALUES ( 1, 'Foo Bar' ), ( 2, 'Jon Dow' );
DECLARE @Addresses TABLE ( AccountID INT, AddressLine VARCHAR(50), City VARCHAR(50) );
INSERT INTO @Addresses ( AccountID, AddressLine, City )
VALUES ( 1, '123 Test Rd', 'New York' ), ( 1, '456 Test Rd', 'New York' ), ( 2, 'Lombard Street', 'San Francisco' ), ( 2, 'Lombard Street', 'San Francisco' );
SELECT
Accounts.AccountID,
AddressRecords.AddressLine,
Addresses.City
FROM @Accounts AS Accounts
INNER JOIN @Addresses AS Addresses
ON Accounts.AccountID = Addresses.AccountID
OUTER APPLY (
SELECT CASE
WHEN ( SELECT COUNT ( DISTINCT ( x.AddressLine ) ) FROM @Addresses AS x WHERE x.AccountID = Accounts.AccountID ) > 1 THEN 'Multiple'
ELSE ( SELECT DISTINCT AddressLine FROM @Addresses AS x WHERE x.AccountID = Accounts.AccountID )
END AS AddressLine
) AS AddressRecords
WHERE
Accounts.AccountID = 1
GROUP BY
Accounts.AccountID, AddressRecords.AddressLine, Addresses.City;
AccountID 2退货
+-----------+-------------+----------+
| AccountID | AddressLine | City |
+-----------+-------------+----------+
| 1 | Multiple | New York |
+-----------+-------------+----------+
也可以将我的加入混合。它并不比其他任何一个都要好,但是无论如何它还是在这里...
+-----------+----------------+---------------+
| AccountID | AddressLine | City |
+-----------+----------------+---------------+
| 2 | Lombard Street | San Francisco |
+-----------+----------------+---------------+