使用 SQL 检索属于多个不同子类别的项目

问题描述 投票:0回答:1

想象一下,我的库存项目分为工程 (Eng) 和信息技术 (IT) 两个主要部门。此外,这些项目进一步分为几个子类别,例如,对于 IT 部门,我在子类别 IT059、IT059L.. 等中拥有项目,而对于 Eng,我在子类别 Eng200、Eng209.. 等中拥有类似的项目。我只需要检索在 IT 和 Eng 子类别中找到的项目。 2 个数据库表是 ItemDepartment

物品表

item_id,    item_name,      date_purchased
101,        A101,           2012-01-01
101,        A101,           2012-01-02
101,        A101,           2012-01-03
101,        A101,           2012-01-04
150,        B150,           2012-01-05
202,        C202,           2012-01-06
202,        C202,           2012-01-07
202,        C202,           2012-01-08
221,        D221,           2012-01-09
303,        E303,           2012-01-10
303,        E303,           2012-01-11
303,        E303,           2012-01-12
351,        F351,           2012-01-13
404,        G404,           2012-01-14
404,        G404,           2012-01-15
414,        H414,           2012-01-16
505,        I505,           2012-01-17
505,        I505,           2012-01-18
516,        J516,           2012-01-19
606,        K606,           2012-01-20
606,        K606,           2012-01-21
606,        K606,           2012-01-22
707,        L707,           2012-01-23
707,        L707,           2012-01-24
707,        L707,           2012-01-25
707,        L707,           2012-01-26
707,        L707,           2012-01-27
707,        L707,           2012-01-28
707,        L707,           2012-01-29
808,        M808,           2012-01-30
808,        M808,           2012-01-31
808,        M808,           2012-02-01
808,        M808,           2012-02-02
909,        N909,           2012-02-03
909,        N909,           2012-02-04
909,        N909,           2012-02-05
909,        N909,           2012-02-05
909,        N909,           2012-02-07
950,        O950,           2012-02-08
950,        O950,           2012-02-09
970,        P970,           2012-02-10
970,        P970,           2012-02-11
970,        P970,           2012-02-12
970,        P970,           2012-02-13
970,        P970,           2012-02-14
999,        Q999,           2012-02-15

部门表

item_id,    department_id
101,        Eng200
101,        IT059
101,        IT059L
101,        IT069
150,        Eng200
202,        Eng209
202,        IT059
202,        IT060L
221,        IT060L
303,        Eng209
303,        IT06.9
303,        IT069
351,        Eng20-
404,        Eng209
404,        IT064
414,        Eng20.1
505,        Eng209
505,        IT060
516,        IT05..
606,        Eng209
606,        IT060M
606,        IT069
707,        Eng209
707,        IT058H
707,        IT059
707,        IT06.0
707,        IT06.9
707,        IT060
707,        IT069
808,        Eng209
808,        IT059
808,        IT059M
808,        IT069
909,        Eng209
909,        IT059
909,        IT060
909,        IT060M
909,        IT069G
950,        Eng20-
950,        IT069
970,        Eng20-
970,        IT058L
970,        IT059
970,        IT059L
970,        IT069
999,        Eng20?

如果我只有 2 个 Department_ids(IT 和 Eng),我可以编写类似于以下的查询:

select max(i.item_id)
from item i
join department d
on i.item_id = d.item_id
group by i.item_id
having count(distinct d.department_id) > 1

但是,就我而言,我有几个部门 ID 需要首先检查,以确定该项目是否满足属于 IT 和 Eng 类别的条件。

预期产量

item_id
101
202
303
404
505
606
707
808
909
950
970

如何检索所需的输出?

sql sql-server join group-by relational-division
1个回答
0
投票

您可以使用

CROSS APPLY
拉出前缀,然后使用
COUNT(DISTINCT Prefix

请注意,您的

Department
表实际上应该称为
DepartmentItem
,因为它不是
Department
的唯一列表。

SELECT
  i.item_id
FROM Item i
JOIN DepartmentItem di ON di.item_id = i.item_id
CROSS APPLY (VALUES(
    CASE WHEN di.department_id LIKE 'IT%' THEN 'IT'
         WHEN di.department_id LIKE 'Eng%' THEN 'Eng'
    END
)) v(Prefix)
WHERE (di.department_id LIKE 'IT%' OR di.department_id LIKE 'Eng%')
GROUP BY
  i.item_id
HAVING COUNT(DISTINCT v.Prefix) = 2;

另请注意,我没有在

v.Prefix
中使用
WHERE
值,因为您无法在其上使用索引。

db<>小提琴

理想情况下,您将有一个单独的

Department
表,其中有一个
DepartmentType
列,然后您可以这样做

SELECT
  i.item_id
FROM Item i
JOIN DepartmentItem di ON di.item_id = i.item_id
JOIN Department d ON d.department_id = di.department_id
WHERE di.Type IN ('IT', 'Eng')
GROUP BY
  i.item_id
HAVING COUNT(DISTINCT di.Type) = 2;
© www.soinside.com 2019 - 2024. All rights reserved.