Sql 找到一对多关系中的任何项是否设置了标志的正确方法是什么?

Sql 找到一对多关系中的任何项是否设置了标志的正确方法是什么?,sql,sql-server,Sql,Sql Server,如果我有以下数据库模式 我想写一个查询,列出所有Bill_项目,但包含一个为true的标志。如果有任何关联的库存项目标记了CheckFlag位,那么正确的方法是什么 我想做这件事的方式是 select *, case when exists(select CheckFlag from inventoryitems inner join Linked_items on Item_c

如果我有以下数据库模式

我想写一个查询,列出所有Bill_项目,但包含一个为true的标志。如果有任何关联的库存项目标记了CheckFlag位,那么正确的方法是什么

我想做这件事的方式是

select *, case when exists(select  CheckFlag
                            from inventoryitems 
                            inner join Linked_items on Item_code = ItemCode 
                            where Bill_Code = BillCode
                                  and CheckFlag = 1
                            ) 
                then 1 else 0 end as flagSet 
from Bill_items

但是,我很确定我没有用正确的方法进行检查,我应该用什么方法进行这样的检查?

是否有理由不直接加入表并使用
行号
返回每个
账单代码的第一行:

select billcode, flagset
from
(
  select b.*, -- replace this with your columns
    i.checkflag flagSet,
    row_number() over(partition by b.billcode order by i.CheckFlag desc) rn
  from Bill_items b
  left join Linked_items l
    on l.Bill_Code = b.BillCode
  left join inventoryitems i
    on l.Item_code = i.ItemCode
) d
where rn = 1;


CheckFlag
有点小,因此结果将是零或一,不需要这样做。

是否有理由不直接加入表,并使用
行编号
返回每个
billcode
的第一行:

select billcode, flagset
from
(
  select b.*, -- replace this with your columns
    i.checkflag flagSet,
    row_number() over(partition by b.billcode order by i.CheckFlag desc) rn
  from Bill_items b
  left join Linked_items l
    on l.Bill_Code = b.BillCode
  left join inventoryitems i
    on l.Item_code = i.ItemCode
) d
where rn = 1;

CheckFlag
是一个位,因此结果将是零或一,不需要这种情况。

尝试以下方法:

select
     Bill_items.billcode
    ,max(cast(CheckFlag as int)) as flagSet 
from Bill_items
join Linked_items 
    on Bill_items.billcode = Linked_items.Bill_Code
join inventoryitems
    on Linked_items.Item_code = inventoryitems.ItemCode 
group by
     Bill_items.billcode
如果您需要包括没有清单项目的账单项目,请尝试以下操作:

select
     Bill_items.billcode
    ,max(isnull(cast(CheckFlag as int),0)) as flagSet 
from Bill_items
left join Linked_items 
    on Bill_items.billcode = Linked_items.Bill_Code
left join inventoryitems
    on Linked_items.Item_code = inventoryitems.ItemCode 
group by
     Bill_items.billcode
这是一个连接到账单项目的派生版本

select
     Bill_items.*
    ,isnull(_CheckFlags.flagSet,0) as flagSet
from Bill_items
left join (
    select
         Linked_items.Bill_Code
        ,max(cast(CheckFlag as int)) as flagSet 
    from Linked_items 
    join inventoryitems
        on Linked_items.Item_code = inventoryitems.ItemCode 
    group by
         Linked_items.Bill_Code
) _CheckFlags
    on Bill_items.billcode = _CheckFlags.Bill_Code
对于不带强制转换的方法,请尝试以下操作:

select
     Bill_items.*
    ,isnull(_CheckFlags.flagSet,0) as flagSet
from Bill_items
left join (
    select
         Linked_items.Bill_Code
        ,CheckFlag as flagSet 
    from Linked_items 
    join inventoryitems
        on Linked_items.Item_code = inventoryitems.ItemCode
    where CheckFlag = 1
    group by
         Linked_items.Bill_Code
        ,CheckFlag
) _CheckFlags
    on Bill_items.billcode = _CheckFlags.Bill_Code
试试这个:

select
     Bill_items.billcode
    ,max(cast(CheckFlag as int)) as flagSet 
from Bill_items
join Linked_items 
    on Bill_items.billcode = Linked_items.Bill_Code
join inventoryitems
    on Linked_items.Item_code = inventoryitems.ItemCode 
group by
     Bill_items.billcode
如果您需要包括没有清单项目的账单项目,请尝试以下操作:

select
     Bill_items.billcode
    ,max(isnull(cast(CheckFlag as int),0)) as flagSet 
from Bill_items
left join Linked_items 
    on Bill_items.billcode = Linked_items.Bill_Code
left join inventoryitems
    on Linked_items.Item_code = inventoryitems.ItemCode 
group by
     Bill_items.billcode
这是一个连接到账单项目的派生版本

select
     Bill_items.*
    ,isnull(_CheckFlags.flagSet,0) as flagSet
from Bill_items
left join (
    select
         Linked_items.Bill_Code
        ,max(cast(CheckFlag as int)) as flagSet 
    from Linked_items 
    join inventoryitems
        on Linked_items.Item_code = inventoryitems.ItemCode 
    group by
         Linked_items.Bill_Code
) _CheckFlags
    on Bill_items.billcode = _CheckFlags.Bill_Code
对于不带强制转换的方法,请尝试以下操作:

select
     Bill_items.*
    ,isnull(_CheckFlags.flagSet,0) as flagSet
from Bill_items
left join (
    select
         Linked_items.Bill_Code
        ,CheckFlag as flagSet 
    from Linked_items 
    join inventoryitems
        on Linked_items.Item_code = inventoryitems.ItemCode
    where CheckFlag = 1
    group by
         Linked_items.Bill_Code
        ,CheckFlag
) _CheckFlags
    on Bill_items.billcode = _CheckFlags.Bill_Code
这应该是可行的(内部子查询将避免您在
group by
子句中添加所有列),而且速度也会更快

SELECT 
  bi.*,
  temp.checkflag
FROM 
  bill_items bi
  LEFT JOIN (
              SELECT 
                max(ii.checkflag) as checkflag,
                li.bill_code
              FROM 
                linked_items li
                JOIN inventory_items ii ON ( ii.item_code = ii.itemCode AND ii.checkflag = 1 ) 
              GROUP BY
                li.bill_code
            ) as temp ON ( temp.bill_code = bi.billCode )
这应该是可行的(内部子查询将避免您在
group by
子句中添加所有列),而且速度也会更快

SELECT 
  bi.*,
  temp.checkflag
FROM 
  bill_items bi
  LEFT JOIN (
              SELECT 
                max(ii.checkflag) as checkflag,
                li.bill_code
              FROM 
                linked_items li
                JOIN inventory_items ii ON ( ii.item_code = ii.itemCode AND ii.checkflag = 1 ) 
              GROUP BY
                li.bill_code
            ) as temp ON ( temp.bill_code = bi.billCode )


如果账单项目没有任何链接项目,该怎么办?这将被排除在结果之外,而不是包含在0标志值中。然后,您将获得具有多个链接项目的账单项目的重复记录。@EstericScreenName我将从加入而不是使用相关子查询开始。我的问题是,您的答案生成的结果集与原始查询不一样。@EstericScreenName您是对的,我的错。我已编辑了我的答案,以包括
行号()
如果账单项目没有任何链接项目该怎么办?这将被排除在结果之外,而不是包含在0标志值中。然后,您将获得具有多个链接项目的账单项目的重复记录。@EstericScreenName我将从加入而不是使用相关子查询开始。我的问题是,您的答案生成的结果集与原始查询不一样。@EstericScreenName您是对的,我的错。我已经编辑了我的答案,包括
行号()
这有什么不正确的地方?你是否没有得到你想要的结果,或者你认为有一种更有效的方法来构造查询?我觉得这将是不有效的,它正在执行N个查询内部选择,其中N是Bill_items中的行数这不正确吗?你是否没有得到你想要的结果,或者你认为有一种更高效的方法来构造查询?我觉得这是不高效的,它正在执行N个查询,其中N是账单项目中的行数+1,用于正确考虑多对多关系并生成与问题查询相同的结果(第二个查询)。如果需要其他列,只需将它们添加到select列表和group by子句中即可。只要不将CheckFlag添加到其中任何一个,结果就不会更改。原始查询中的*只会返回Bill_items表中的所有列,因此这就是我的结果集中包含的所有列。对于示例来说,它是一个缩减集,并且Bill_item中有很多被引用的列,我必须测试我的老方法和这种方法,看看结果如何。如果你不能按所有字段分组,你可以导出它,并将其加入到你对Bill_items.billcode的查询中,该查询应该比子查询更有效。情况并非总是如此,但我尽量避免子查询。我编辑了答案,将派生版本加入到所有账单项目的查询中。+1用于正确考虑多对多关系并生成与问题查询相同的结果,如果需要其他列,只需将它们添加到select列表和group by子句中即可。只要不将CheckFlag添加到其中任何一个,结果就不会更改。原始查询中的*只会返回Bill_items表中的所有列,因此这就是我的结果集中包含的所有列。对于示例来说,它是一个缩减集,并且Bill_item中有很多被引用的列,我必须测试我的老方法和这种方法,看看结果如何。如果你不能按所有字段分组,你可以导出它,并将其加入到你对Bill_items.billcode的查询中,该查询应该比子查询更有效。情况并非总是如此,但我尽量避免子查询。我编辑了答案,将派生版本加入到所有账单项目的查询中。由于项目代码是伪造键,在链接项目-库存项目链接上使用内部连接会更好吗?在链接项目-库存项目链接上使用内部连接会更好吗由于项目_代码是伪造的密钥,因此这一点更好吗?