【问题标题】:SQL Show items that don't exist in other categoriesSQL 显示其他类别中不存在的项目
【发布时间】:2014-07-17 04:41:58
【问题描述】:

我有一个层级、类别和项目表。对于 Tier = 2,每个类别应具有相同的项目数。我想显示每个类别中缺少的项目。

这是一个示例表:

IF OBJECT_ID('tempdb..#Items') IS NOT NULL DROP TABLE #Items
CREATE TABLE #Items (
    Tier        int,
    Category    nvarchar(25),
    Item        nvarchar(25)
)

INSERT INTO #Items
SELECT '2', 'CategoryA',    'Item1'
UNION ALL
SELECT '2', 'CategoryA',    'Item2'
UNION ALL
SELECT '2', 'CategoryA',    'Item3'
UNION ALL
SELECT '2', 'CategoryB',    'Item1'
UNION ALL
SELECT '2', 'CategoryB',    'Item3'
UNION ALL
SELECT '2', 'CategoryC',    'Item1'
UNION ALL
SELECT '2', 'CategoryC',    'Item2'
UNION ALL
SELECT '2', 'CategoryC',    'Item3'
UNION ALL
SELECT '2', 'CategoryC',    'Item4'

SELECT
    Tier,
    Category,
    Item
FROM #Items
ORDER BY Tier, Category, Item

Tier    Category    Item
2   CategoryA   Item1
2   CategoryA   Item2
2   CategoryA   Item3
2   CategoryB   Item1
2   CategoryB   Item3
2   CategoryC   Item1
2   CategoryC   Item2
2   CategoryC   Item3
2   CategoryC   Item4

如果我显示每个类别中的项目数:

SELECT
    Tier,
    Category,
    COUNT(Item) as ItemCount
FROM #Items
GROUP BY Tier, Category

它们应该都有相同的 4 项:

Tier    Category    ItemCount
2   CategoryA   3
2   CategoryB   2
2   CategoryC   4

我想显示每个类别中缺少的项目的列表。这可能有效,但显然很笨拙,只是为了呈现我希望看到的数据。

SELECT DISTINCT
    Tier,
    'CategoryA' as [Category],
    Item
FROM #Items i
WHERE Item NOT IN (SELECT Item from #Items WHERE Category = 'CategoryA')
UNION ALL
SELECT DISTINCT
    Tier,
    'CategoryB' as [Category],
    Item
FROM #Items i
WHERE Item NOT IN (SELECT Item from #Items WHERE Category = 'CategoryB')
UNION ALL
SELECT DISTINCT
    Tier,
    'CategoryC' as [Category],
    Item
FROM #Items i
WHERE Item NOT IN (SELECT Item from #Items WHERE Category = 'CategoryC')

并显示结果:

Tier    Category    Item
2   CategoryA   Item4
2   CategoryB   Item2
2   CategoryB   Item4

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012


    【解决方案1】:

    您可以使用项的笛卡尔积来执行此操作,然后取出源表中不存在的项:

    SELECT DISTINCT
        i1.Tier,
        i1.[Category],
        i2.Item
    FROM Items i1, Items i2
    WHERE i2.Item NOT IN (SELECT Item from Items WHERE Category = i1.Category)
    

    结果:

    TIER    CATEGORY    ITEM
    ----    --------    -----
    2       CategoryA   Item4
    2       CategoryB   Item2
    2       CategoryB   Item4
    

    你可以test the query here

    【讨论】:

    • 学习这样的新东西让我想学习更多这样的新东西 :) 谢谢
    • 记录很多的时候会很慢。
    【解决方案2】:

    我会使用交叉连接来执行此操作,然后将其连接回自身:

    select
         _Categories.category
        ,_Items.item
    from(
      select distinct
          category
      from Items
    ) _Categories
    cross join (
      select distinct
          item
      from items
    ) _Items
    left join Items _ActualItems
      on _ActualItems.category = _Categories.category
      and _ActualItems.item = _Items.item
    where _ActualItems.item is null
    

    这是一个SQL Fiddle Example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      相关资源
      最近更新 更多