0

我正在努力理解这个 sql。

我有一个函数,它返回与物料清单 BOM 关联的项目列表。

sql 选择的结果

SELECT
    BOM,
    ITEMID,
    QTY
FROM boms
WHERE
    bom='A'

BOM     | ITEMID     | QTY
A       | ITEMB      | 1
A       | ITEMC      | 2

现在使用该结果集,我希望查询我的销售表以查找 ITEMB 和 ITEMC 的销售量足够大。

salestable的格式如下

SELECT
    salesid,
    itemid,
    sum(qtyordered) 'ordered'
FROM salesline
WHERE
    itemid='ITEMB'
    or itemid='ITEMC'
GROUP BY salesid, itemid

这会给我类似的东西

salesid   | itemid   | ordered
SO-10000  | ITEMB    | 1
SO-10001  | ITEMB    | 1
SO-10001  | ITEMC    | 1
SO-10002  | ITEMB    | 1
SO-10002  | ITEMC    | 2

理想情况下,我只想退回 SO-10002,因为这是唯一一次售出所有必要单位的销售。

任何建议,将不胜感激。理想情况下,一个查询将是理想的,但我不确定这是否可能。性能不是必须的,因为这将在每周凌晨运行一次。

编辑

在始终出色的帮助下,代码现已完成。我已将其全部打包到一个 UDF 中,该 UDF 仅返回指定 BOM 在指定时间段内的销售额。

功能是

CREATE FUNCTION [dbo].[BOMSALES] (@bom varchar(20),@startdate datetime, @enddate datetime)
RETURNS TABLE
AS
RETURN(
select count(q.SALESID) SOLD FROM (SELECT s.SALESID
FROM
 (
   SELECT s.SALESID, ITEMID, SUM(qtyordered) AS SOLD
   FROM salesline s  inner join SALESTABLE st on st.salesid=s.SALESID
   where st.createddate>=@startdate and st.CREATEDDATE<=@enddate and st.salestype=3
   GROUP BY s.SALESID, ITEMID
 ) AS s
JOIN dbo.BOM1 AS b ON b.ITEMID = s.ITEMID AND b.QTY <= s.SOLD 
where b.BOM=@bom
GROUP BY s.SALESID
HAVING COUNT(*) = (SELECT COUNT(*) FROM dbo.BOM1 WHERE BOM = @bom)) q
)
4

3 回答 3

1

这应该返回完全匹配的所有销售,即相同的 itemid 和相同的数量:

SELECT s.salesid 
FROM
 (
   SELECT salesid, itemid, SUM(qtyordered) AS ordered
   FROM salesline AS s 
   GROUP BY salesid, itemid
 ) AS s
JOIN 
  boms AS b
ON b.itemid = s.itemid
AND b.QTY = s.ordered
WHERE b.BOM='A'
GROUP BY s.salesid
HAVING COUNT(*) = (SELECT COUNT(*) FROM boms WHERE BOM='A');

如果您想退回数量大于 boms.qty 的销售,您必须相应地更改联接:

JOIN 
  boms AS b
ON b.itemid = s.itemid
AND b.QTY <= s.ordered

未经测试...

于 2013-09-16T13:33:55.877 回答
0

我认为这可能会为您提供所需的结果。您必须用您的 bom 替换 @BOM:

SELECT
    DISTINCT salesid
FROM
    salesline sl
INNER JOIN boms b ON
    b.bom = @BOM
    AND b.itemid = sl.itemid
GROUP BY salesid, itemid
HAVING SUM(qtyordered) >= b.qty

据我所知,第一个查询用于获取返回合格销售的阈值?根据您的示例数据行,我假设 salesline 表中每个 salesid + itemid (基本上充当双字段主键)只有一行?如果这是真的,我认为不需要像您在第二个示例查询中那样进行 SUM。如果我的任何假设有误,请告诉我,我会调整我的答案。

于 2013-09-16T13:35:57.923 回答
0

您可以执行此聚合和having子句:

select salesid
from salesline sl
group by salesid
having sum(case when itemid = 'ITEMB' then 1 else 0 end) > 0 and
       sum(case when itemid = 'ITEMA' then 1 else 0 end) > 0;

子句中的每个条件都在having计算每个项目的行数。

于 2013-09-16T13:31:58.243 回答