【问题标题】:T-SQL Group CheckT-SQL 组检查
【发布时间】:2016-05-20 10:14:14
【问题描述】:

我有三个表 - Table_1、Table_2 和 Table_3。以下是每个的样子:

Table_1

   ID  | TicketID | Rule  
---------------------------
    1  |    101   | NULL

Table_2

    TicketID | Location
---------------------------  
       101   | A
       101   | B

Table_3

Location | Rule
--------------------
    A    |  R1
    B    |  R1
    A    |  R2
    B    |  R2
    C    |  R2

我的目标是填充 Table_1 中的 Rule 列(这应该是 Table_3 中 Rule 列的选择不同)。流程应该是:

  • 从 Table_1 中获取 TicketID。在 TicketID 上将 Table_1 连接到 Table_2,并获取与该票证关联的位置。
  • 查找 Table_3 并检查需要应用什么规则。检查需要在组级别。例如,在此示例中,工单 101 具有位置 A、B。 Table_3 有针对规则 R1 的 A、B,但也有针对规则 R2 的 A、B、C。正确的规则应该是 R1,因为 Ticket 101 没有分配给位置 C。希望这有意义。实现这一目标的最简单方法是什么?提前致谢!

【问题讨论】:

  • 听起来像是功课。你试过什么了?究竟是什么,你坚持?
  • 如果一张票只有一个位置(例如,A),应该怎么办?对于具有 更多 个位置(例如,A, B, C, D)的票证应该怎么办?
  • 您要插入到第一个表,还是更新第一个表?请显示您想要的输出。
  • 另外,R3 在表 3 中是否也只有 AB 的行?如果是,应该选择哪条规则?
  • @Damien_The_Unbeliever 如果一张票有一个位置 A,那么输出应该类似于“多个”。实际上,这不应该发生。如果它有 A、B、C、D 并且该组合在 Table_3 中不可用,则它会转到另一个表进行相同的检查,但基于不同的属性。

标签: sql sql-server sql-server-2008 tsql sql-server-2012


【解决方案1】:

请尝试以下代码。它在 SQL Server 2012 中运行良好。

DECLARE @table_1 TABLE
(ID int, TicketID int, [Rule] Varchar(10))

DECLARE @table_2 TABLE
(TicketID int, Location Varchar(10))

DECLARE @table_3 TABLE
(Location Varchar(10),[Rule] Varchar(10))

INSERT @table_1
(ID,TicketID,[Rule])
VALUES
(1,101,NULL)

INSERT @table_2
(TicketID,Location)
VALUES
(101,'A'),
(101,'B')

INSERT @table_3
(Location,[Rule])
VALUES
('A','R1'),
('B','R1'),
('A','R2'),
('B','R2'),
('C','R2')

SELECT DISTINCT [RULE] FROM @table_3 t3 WHERE t3.Location IN
(SELECT t2.Location FROM @table_2 t2 INNER JOIN @table_1 t1 ON t1.TicketID = t2.TicketID)
AND [RULE] NOT IN 
(SELECT t.[RULE] FROM @table_3 t WHERE t.Location NOT IN 
(SELECT t2.Location FROM @table_2 t2 INNER JOIN @table_1 t1 ON t1.TicketID = t2.TicketID))

【讨论】:

  • 谢谢!这很好,但我刚刚将@table_2 更改为现在包含第三条记录(101,'C'),它现在返回 R1 和 R2,而我只需要 R2?
【解决方案2】:

试试这个..

SELECT t1.TicketID
,t2.[Rule]
FROM (SELECT DISTINCT t2.TicketID,[Rule]
FROM @table_3 t3 INNER JOIN 
     @table_2 t2 ON t2.Location = t3.Location) t2
INNER JOIN @table_1 t1 ON t2.TicketID = t1.TicketID

将此选择语句与上述声明的表变量一起使用

【讨论】:

    【解决方案3】:
    --http://stackoverflow.com/questions/37344006/t-sql-group-check
    set nocount on
    drop table #temp
    DECLARE @table_1 TABLE
    (ID int, TicketID int, [Rule] Varchar(10))
    
    DECLARE @table_2 TABLE
    (TicketID int, Location Varchar(10),obs int)
    
    DECLARE @table_3 TABLE
    (Location Varchar(10),[Rule] Varchar(10), obs int)
    
    INSERT @table_1
    (ID,TicketID,[Rule])
    VALUES
    (1,101,NULL)
    
    INSERT @table_2
    (TicketID,Location)
    VALUES
    (101,'A'),
    (101,'B'),
    --(101,'C')
    (102,'A'),
    (102,'B'),
    (102,'C'),
    (102,'S')
    
    INSERT @table_3
    (Location,[Rule])
    VALUES
    ('A','R1'),
    ('B','R1'),
    ('A','R2'),
    ('B','R2'),
    ('C','R2'),
    ('S','R2')
    
    declare @table_4 table (src varchar(2), id varchar(3), obs int)
    insert into @table_4
    select  't2', [ticketid], count(*) from @table_2 group by [ticketid]
    
    Insert into @table_4
    select  't3',[rule], count(*) from @table_3 group by [rule]
    
    update  @table_2
    set     obs = t4.obs
    from    @table_2 t2
    join    @table_4 t4 on t4.id = t2.ticketid
    where   t4.src = 't2' 
    
    update  @table_3
    set     obs = t4.obs
    from    @table_3 t3
    join    @table_4 t4 on  rtrim(t4.id) = rtrim(t3.[rule])
    where   t4.src = 't3'
    
    select  t2.ticketid,t2.location as t2location,t2.obs as t2obs,t3.location as t3location,t3.[Rule],t3.obs as t3obs
    into    #temp
    from    @table_2 t2
    full    join    @table_3 t3 on t3.location = t2.location
    
    delete  #temp
    where   [rule] in (select [rule] from #temp where ticketid is null)     
    
    --select  t.*
    --from  #temp t
    
    select  distinct ticketid,[rule]
    from    #temp
    where   t2location = t3location and t2obs = t3obs 
    

    【讨论】:

    • 不性感,可能不是最佳的,但它似乎工作。诀窍似乎是了解有多少位置与表 2 中的票证和表 3 中的规则相关,然后“忘记”所有规则/位置,其中规则中的任何规则/位置在加入表 3 时返回空值。
    【解决方案4】:

    试试这个代码:

    SELECT DISTINCT [RULE] FROM Table_3 t3 WHERE t3.Location IN
    (SELECT t2.Location FROM Table_2 t2 INNER JOIN Table_1 t1 ON t1.TicketID = t2.TicketID)
    AND [RULE] NOT IN 
    (SELECT t.[RULE] FROM Table_3 t WHERE t.Location NOT IN 
    (SELECT t2.Location FROM Table_2 t2 INNER JOIN Table_1 t1 ON t1.TicketID = t2.TicketID))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      相关资源
      最近更新 更多