多方进行状态检查的1对多

时间:2017-04-20 14:18:29

标签: sql oracle

我是这个sql世界的新手。在我是一名SQL和SQL知识有限的开发人员之后简单的连接。我在为一对多关系编写sql join时遇到了问题。这是我的问题 -

例如,如果我有一个Customer表:

id   Name         address
1    manoj        Japan
2    Sunil        US

票证表格:

id   customerid     ticketstatus
1    1               closed
2    1               closed
3    2               closed
4    1               open
5    2               closed

现在加入后我想要的是:

id        customername     ticketstatus
2         sunil            closed

所以我只想要那些已经关闭所有门票状态的客户。

任何人都可以帮忙写这个吗?

6 个答案:

答案 0 :(得分:1)

请尝试以下方法......

SELECT id,
       Name
FROM Customer
WHERE id NOT IN ( SELECT customerid
                  FROM Tickets
                  WHERE ticketstatus <> 'closed'
                );

此语句列出了Customer的{​​{1}}和id,其name未显示在id&#39列表中; s(来自customerid表)对应于Tickets以外的状态。

除非您希望显示closed,否则无需加入,即使它始终为ticketstatus。在这种情况下,请尝试以下内容......

closed

请注意要包含在输出中的额外字段以及执行​​的SELECT Customer.id AS id, Name, ticketstatus FROM Customer JOIN Tickets ON Customer.id = Tickets.customerid WHERE id NOT IN ( SELECT customerid FROM Tickets WHERE ticketstatus <> 'closed' ) GROUP BY Customer.id; 。由于客户可能有多个JOIN closed,因此所选字段的多个实例是可能的,我还添加了Ticket子句以将输出减少到每个只有一个记录GROUP BY Customer.id

如果您有任何问题或意见,请随时发表评论。

答案 1 :(得分:1)

Tickets表上的标准聚合(子)查询,后跟连接以获取客户名称:

with
     customer ( id, name, address ) as (
       select 1, 'Manoj', 'Japan' from dual union all
       select 2, 'Sunil', 'US'    from dual
     ),
     tickets ( id, customerid, ticketstatus ) as (
       select 1, 1, 'closed' from dual union all
       select 2, 1, 'closed' from dual union all
       select 3, 2, 'closed' from dual union all
       select 4, 1, 'open'   from dual union all
       select 5, 2, 'closed' from dual
     )
-- END of test data (not part of the solution!)
-- SQL query begins BELOW THIS LINE
select s.id, c.name, 'closed' as ticketstatus
from   (
         select   customerid as id
         from     tickets
         group by customerid
         having   min(ticketstatus) = 'closed'
            and   max(ticketstatus) = 'closed'
       ) s
       join customer c
       on s.id = c.id
;

ID  NAME   TICKETSTATUS
--  -----  ------------
 2  Sunil  closed

这假定ticketstatus不能为NULL - 否则必须小心谨慎,因为min()max()会忽略空值。

答案 2 :(得分:0)

试试这个: -

        Select distinct a.ID, a.Name as customername, b.ticketstatus
            from
            Customer a
            inner join
            Tickets b
            on a.Id=b.CustomerId
            where a.Id not in
           (select CustomerId from 
            Tickets where ticketstatus <> 'closed'
           ) 
           and b.ticketstatus='closed'
            ;

    OR

   //With Same logic and different approach

    Select distinct a.ID, a.Name as customername, b.ticketstatus
        from
        Customer a

        inner join

       (select CusotomerID,ticketstatus from Tickets 
        where ticketstatus='closed'
       ) b

        on a.Id=b.CustomerId
        where a.Id not in
       (select CustomerId from 
        Tickets where ticketstatus <> 'closed'
       ) ;

答案 3 :(得分:0)

您想要的是找到至少拥有一张票并且没有未关闭票的所有用户:

SELECT c.id, c.name AS customername
  FROM customers c
 WHERE EXISTS ( SELECT 1 FROM tickets t
                 WHERE t.customerid = c.id )
   AND NOT EXISTS ( SELECT 1 FROM tickets t
                     WHERE t.customerid = c.id
                       AND t.ticketstatus != 'closed' );

希望这有帮助。

答案 4 :(得分:0)

我会加入客户和门票来定义所需的结果集。 然后我会排除所有没有关闭的门票的顾客。 我在ticketstatus上使用了coalesce,以防任何值都为null。

SELECT Distinct C.ID, C.Name as CustomerName, T.TicketStatus
FROM Customer C
INNER JOIN Tickets T
 on C.ID = T.customerID
WHERE NOT EXISTS (SELECT 1 
                  FROM TICKETS T2
                  WHERE coalesce(TicketStatus,'NULL') <> 'closed'
                  and T2.CustomerID = T.CustomerID)

答案 5 :(得分:-2)

你正在寻找这样的东西:

select distinct a.customername, b.ticketstatus from table1 a
join table2 b on a.id = b.customerid 
where b.ticketstatus = 'closed'