SQL Server 2014:如何获取仅包含特定列的不同值行的记录

SQL Server 2014 : how to get records that have rows of different values of only particular column

我们的客户在我们这里有他们车辆的账户。一些客户有多辆车,因此有多个车牌。有时,一些客户的车辆也有不同的保险账户。

我需要一份帐户列表:

  1. 超过 1 个车牌和
  2. 超过1个保险账户ID

我正在使用 3 tables:

关系:

A.AccountId = P.AccountId = E.AccountId

到目前为止我的代码:

SELECT 
    A.AccountNumber, A.AccountId, A.CurrentBalance,
    E.NotificationDt,
    P.LicPlateNo, A.RegistrationTypeId, P.InsuranceAccountId
FROM 
    Account A
INNER JOIN 
    Plate P ON A.AccountId = P.AccountId
INNER JOIN  
    EventLog E ON A.AccountId = E.AccountId
WHERE 
    A.RegistrationTypeId = 3
    AND P.EndDate IS NULL               
    AND A.AccountStatusId = 1           
    AND A.DelinquencyStatusId = 11
    AND E.EventId = 64
    AND P.PlateStatusId = 1
ORDER BY 
    AccountNumber, A.AccountId, P.LicPlateNo

我的示例数据如下所示:

+---------+---------+---------+-------------+----------+---+--------+
|AccNo    | AccId   |CurrBal  |NotifDt      |LicPlateNo|RTI|InsAccId|
+---------+---------+---------+-------------+----------+---+--------+
|21234561 |123456   |    56.79|   2017-01-01|ABC123    |  3|1234ABC |
|21234572 |123457   |    83.25|   2017-01-03|DEF345    |  3|345DEF  |
|22345672 |234567   |   104.38|   2017-01-03|GHI345    |  3|567GHI  |
|22345672 |234568   |   104.38|   2017-01-03|JKL678    |  3|789MNO  |
+---------+---------+---------+-------------+----------+---+--------+

在我的示例数据中,最后两列用于相同的 AccountNumber,但具有不同的 LicencePlateNos 和不同的 Insurance AccountIds

我希望我的数据如下所示:

+---------+---------+---------+-------------+----------+---+--------+
|22345672 |234567   |   104.38|   2017-01-03|GHI345    |  3|567GHI  |
|22345672 |234568   |   104.38|   2017-01-03|JKL678    |  3|789MNO  |
+---------+---------+---------+-------------+----------+---+--------+

给我该数据的代码是什么?

我尝试使用 GROUP BY... HAVING 子句,但这只给我唯一的 AccountNumber 有多个牌照的。我想展示不同的车牌号码和不同的 InsuranceAccountIDs。

一种简单的方法是使用您的查询作为基础并计算多行的值:

SELECT a.*
FROM (SELECT A.AccountNumber, A.AccountId, A.CurrentBalance, E.NotificationDt,
             P.LicPlateNo, A.RegistrationTypeId, P.InsuranceAccountId,
             COUNT(*) OVER (PARTITION BY A.AccountNumber) as cnt
      FROM Account A INNER JOIN
           Plate P
           ON A.AccountId = P.AccountId INNER JOIN
           EventLog E
           ON A.AccountId = E.AccountId
      WHERE A.RegistrationTypeId = 3 AND
            P.EndDate IS NULL AND  
            A.AccountStatusId = 1 AND        
            A.DelinquencyStatusId = 11 AND
            E.EventId = 64 AND
            P.PlateStatusId = 1
     ) a
WHERE cnt > 1;   
ORDER BY AccountNumber, AccountId, LicPlateNo;

执行此操作的一种简单方法是加入一个结果集,该结果集允许您检查其中一个或两个条件。只需包含适当的过滤子句:

...
INNER JOIN EventLog E ON A.AccountId = E.AccountId

INNER JOIN
(
    SELECT
        Plate.AccountId,
        LicensePlateCount = COUNT(DISTINCT Plate.LicPlateNo),
        InsuranceAccountCount = COUNT(DISTINCT Plate.InsuranceAccountId)
    FROM
        Plate
    WHERE
        Plate.EndDate IS NULL
        AND Plate.PlateStatusId = 1
    GROUP BY
        Plate.AccountId
) PlateAccounts ON A.AccountId = PlateAccounts.AccountId
    -- 1) More than 1 License Plate:
    AND PlateAccounts.LicensePlateCount > 1
    -- 2) More than 1 Insurance Account IDs:
    AND PlateAccounts.InsuranceAccountCount > 1

WHERE A.RegistrationTypeId = 3
...