Sql 找到一对多关系中的任何项是否设置了标志的正确方法是什么?
如果我有以下数据库模式 我想写一个查询,列出所有Bill_项目,但包含一个为true的标志。如果有任何关联的库存项目标记了CheckFlag位,那么正确的方法是什么 我想做这件事的方式是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
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的查询中,该查询应该比子查询更有效。情况并非总是如此,但我尽量避免子查询。我编辑了答案,将派生版本加入到所有账单项目的查询中。由于项目代码是伪造键,在链接项目-库存项目链接上使用内部连接会更好吗?在链接项目-库存项目链接上使用内部连接会更好吗由于项目_代码是伪造的密钥,因此这一点更好吗?