1

如果我有以下数据库架构

在此处输入图像描述

而且我想编写一个列出所有 Bill_Items 的查询,但包含一个标志,如果任何关联的库存项目标有 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

但是我相当肯定我没有以正确的方式这样做,我应该以什么方式进行这样的检查?

4

3 回答 3

4

试试这个:

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

如果您需要在不包含库存项目的情况下包含 Bill_items,请尝试以下操作:

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

试试这个没有 CAST 的方法:

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
于 2013-05-31T17:29:16.897 回答
3

这应该可以工作(内部子查询将使您免于添加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 )
于 2013-05-31T17:39:31.103 回答
2

您是否有理由不只是加入表并使用 arow_number返回每个表的第一行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;

请参阅带有演示的 SQL Fiddle

有点所以结果将CheckFlag是零或一,应该不需要 CASE。

于 2013-05-31T17:26:58.030 回答