SQL:一列有不同的类型,如何查询

时间:2017-11-15 17:50:26

标签: sql sql-server

我会尽力解释我的问题,但是我在SQL中的大部分经验都是自学,所以请耐心等待。

我有一个表[limit_table],它有一个名为[amount]的列,但是这个limit_table.amount列保存了一个数量但是针对不同的限制类型,限制类型由名为LimitTypeid的列确定,该列有一个外键链接到另一个表[LimitType]

limit_table还有一个指向[client]表的外键链接。

我想要做的是获取[client]表中每个客户端的限制,其中LimitType = x,这些结果我还想知道客户端是否为LimitType为y,即使它没有&#39存在。

对于我的生活,我无法让它发挥作用?任何指针都很棒我尝试使用客户端表中的client.id加入/左外连接回客户端表,但这似乎没有用。

因此LimitType X必须存在(可以为零但不为NULL)但LimitType y是可选的。

希望以看起来基本上像

的结果结束
Client   LimitTypeXAmount   LimitTypeYAmount
ClientA  15000.00           1000.00
ClientB  10000.00           NULL
ClientC  0                  1000.00

以下是我尝试的先前查询:

SELECT CL.CLIENT, LIM.AMOUNT AS LIMITTYPEXAMOUNT, LIM2.AMOUNT AS LIMITTYPEYAMOUNT, FROM CLIENT CL1 
INNER JOIN LIMIT LIM1 ON LIM1.CLIENTID = CL1.ID
INNER JOIN LIMITTYPE LT1 ON LIM1.LIMITTYPEID = LT1.ID AND LT1.TYPE = 'X'
LEFT OUTER JOIN CLIENT CL2 ON CL1.ID = CL2.ID
LEFT OUTER JOIN LIMIT LIM2 ON LIM2.CLIENTID = CL2.ID
LEFT OUTER JOIN LIMITTYPE LT2 ON LIM2.LIMITTYPEID = LT2.ID AND LT2.TYPE = 'Y'

下面假定的架构(由主持人添加):

create table Client (Id int not null, Client varchar(10) not null);
create table Limit (Id int not null, ClientId int not null, Amount decimal (8, 2) not null, LimitTypeId int not null);
create table LimitType (Id int not null, Type char(1) not null);

insert into LimitType (Id, Type) values (1, 'X'), (2, 'Y');
insert into Client (Id, Client) values (1, 'ClientA'), (2, 'ClientB'), (3, 'ClientC');
insert into Limit (Id, ClientId, Amount, LimitTypeId) values
    (1, 1, 15000.00, 1), (2, 1, 1000.00, 2), -- ClientA  15000.00    1000.00
    (3, 2, 10000.00, 1),                     -- ClientB  10000.00       NULL
    (4, 3,     0.00, 1), (5, 3, 1000.00, 2)  -- ClientC      0.00    1000.00
;

2 个答案:

答案 0 :(得分:0)

您的查询似乎不对。将拼写错误LIM.AMOUNT修复为LIM1.AMOUNT。第二个客户表无用:LEFT OUTER JOIN CLIENT CL2,您可以删除该行,并在其他任何地方将CL2替换为CL1

答案 1 :(得分:0)

我不完全确定为什么你有LIMITTYPE表。我假设该表中只有一行TYPE = 'Y'。因此,首先将其作为内部联接连接到那一行,然后您可以链接到相应的LIMITTYPEID。我不清楚的是TYPE不仅仅是LIMIT的属性。您正在引用CLIENT表的两个不同实例,但这似乎是不必要的,我将其删除了。

select
c.Client, l1.Amount as LimitTypeXAmount, l2.Amount as LimitTypeYAmount
from
    Client c
    inner join Limit as l1 on l1.ClientId = c.Id
    inner join LimitType as lt1 on lt1.Id = l1.LimitTypeId and lt1.Type = 'X'
    inner join LimitType as lt2 on lt2.Type = 'Y'
    left outer join Limit as l2 on l2.ClientId = c.Id and l2.LimitTypeId = lt2.Id;

假设有效,你可以在之前的三个连接中镜像相同的逻辑。我会留下那些人。

另一种方法使用派生表:

-- derived table
SELECT
    C.CLIENT,
    L1.AMOUNT AS LIMITTYPEXAMOUNT,
    L2.LIMITTYPEYAMOUNT
FROM 
    CLIENT C 
    INNER JOIN LIMIT L1 ON L1.CLIENTID = C.ID
    INNER JOIN LIMITTYPE LT1 ON LT1.ID = L1.LIMITTYPEID
    LEFT OUTER JOIN (
        SELECT
            L.CLIENTID, L.AMOUNT AS LIMITTYPEYAMOUNT
        FROM 
            LIMIT L
            INNER JOIN LIMITTYPE LT ON LT.ID = L.LIMITTYPEID
        WHERE
            LT.TYPE = 'Y'
    ) AS L2 ON L2.CLIENTID = C.ID
WHERE
    LT1.TYPE = 'X';

只是为了好玩,outer apply

-- outer apply
SELECT
    C.CLIENT,
    L1.AMOUNT AS LIMITTYPEXAMOUNT,
    L2.LIMITTYPEYAMOUNT
FROM 
    CLIENT C 
    INNER JOIN LIMIT L1 ON L1.CLIENTID = C.ID
    INNER JOIN LIMITTYPE LT1 ON LT1.ID = L1.LIMITTYPEID
    OUTER APPLY (
        SELECT
            L.AMOUNT AS LIMITTYPEYAMOUNT
        FROM 
            LIMIT L
            INNER JOIN LIMITTYPE LT ON LT.ID = L.LIMITTYPEID
        WHERE
            LT.TYPE = 'Y' AND L.CLIENTID = C.ID
    ) AS L2
WHERE
    LT1.TYPE = 'X';

编辑:我想我有点生疏,因为我还没有立即认识到这是一个连接顺序问题。这是您可以学习的另一种方法。它具有在一些旧系统上工作的优势,其中没有其他选项。

select
    c.Client, l1.Amount as LimitTypeXAmount, l2.Amount as LimitTypeYAmount
from
    Client c
    inner join Limit as l1
        inner join LimitType as lt1
            on lt1.Id = l1.LimitTypeId and lt1.Type = 'X'
        on l1.ClientId = c.Id

    left outer join Limit as l2
        inner join LimitType as lt2
            on l2.LimitTypeId = lt2.Id and lt2.Type = 'Y'    
        on l2.ClientId = c.Id;

在此播放:http://rextester.com/WJZ23471