SQL 数据透视表产生重复项

发布于 2024-12-09 15:18:23 字数 2121 浏览 1 评论 0原文

开发人员,

我是数据透视表的新手,并且在重复方面遇到了一些问题。我的表格在旋转之前看起来像这样:

位置 | 食物
田纳西州 |梨
田纳西州 |橙色
佛罗里达州 |橙色
佛罗里达州 |苹果
弗吉尼亚州 | pear

这是要旋转的代码,运行良好:

SELECT PivotTable.location, [apple], [orange], [pear]
FROM
(SELECT location, food FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable

这会产生如下输出:

Location | 苹果 | 橙色 |
田纳西州 | 0 | 1 | 1
佛罗里达州 | 1 | 1 | 0
弗吉尼亚州 | 0 | 0 | 1

正如我所说,效果很好。但是,我在原始表格中添加了新的注释列,如下所示:

位置 | 食物 | apple_comments | orange_comments | pear_comments

田纳西州 |梨|空 |空 |空
田纳西州 |橙色|空|非常多汁|空
佛罗里达州 |橙色|空|空|空
佛罗里达州 |苹果|清脆|空 |空
弗吉尼亚州 |梨|空 |空|美味

这是我修改后的数据透视表来解释评论:

SELECT PivotTable.location, [apple], [apple_comments], [orange], [orange_comments], [pear], [pear_comments]
FROM
(SELECT location, food, apple_comments, orange_comments, pear_comments FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable

这会产生如下输出:

位置 | 苹果 | apple_comments | 橙色 | Orange_comments | | Pear_comments
田纳西州 | 0 |空| 0 |空| 1 |空
田纳西州 | 0 |空 | 1 |非常多汁| 0 |空
佛罗里达州 | 0 |空 | 1 |空| 0 |空
佛罗里达州 | 1 |清脆| 1 |空| 0 |空
弗吉尼亚州 | 0 |空 | 1 |空 | 1 |因此

,本质上,当为存在多个位置的每个条目添加注释时,它会创建一个重复行。对于弗吉尼亚州,只有一个条目,因此该行结果很好。

看来我需要再做一次调整或其他什么。谁能就我哪里出错提出建议?

对不起。所需的输出应如下所示:

位置 | 苹果 | apple_comments | 橙色 | Orange_comments | | Pear_comments
田纳西州 | 0 |空 | 1 |非常多汁| 1 |空
佛罗里达州 | 1 |清脆| 1 |空| 0 |空
弗吉尼亚州 | 0 |空 | 1 |空 | 1 |美味

本质上,将重复项合并到一行中。

谢谢。

Developers,

I am new to pivot tables, and am having a little problem with duplicates. My table, before pivoting looks like so:

location | food
Tennessee | pear
Tennessee | orange
Florida | orange
Florida | apple
Virginia | pear

Here is the code to pivot, which works fine:

SELECT PivotTable.location, [apple], [orange], [pear]
FROM
(SELECT location, food FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable

This produces an output like so:

Location | Apple | Orange | Pear
Tennessee | 0 | 1 | 1
Florida | 1 | 1 | 0
Virginia | 0 | 0 | 1

Which as I said works fine. However, I added new columns for comments to my original table, like so:

location | food | apple_comments | orange_comments | pear_comments

Tennessee | pear | NULL | NULL | NULL
Tennessee | orange | NULL | very juicy | NULL
Florida | orange | NULL | NULL | NULL
Florida | apple | crisp | NULL | NULL
Virginia | pear | NULL | NULL| tasty

Here is my altered pivot table to account for the comments:

SELECT PivotTable.location, [apple], [apple_comments], [orange], [orange_comments], [pear], [pear_comments]
FROM
(SELECT location, food, apple_comments, orange_comments, pear_comments FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable

This produces an output like so:

Location | Apple | apple_comments | Orange | Orange_comments | Pear | Pear_comments
Tennessee | 0 | NULL | 0 | NULL | 1 | NULL
Tennessee | 0 | NULL | 1 | very juicy | 0 | NULL
Florida | 0 | NULL | 1 | NULL | 0 | NULL
Florida | 1 | crisp | 1 | NULL | 0 | NULL
Virginia | 0 | NULL | 1 | NULL | 1 | tasty

So, essentially, it is creating a duplicate row when comments are added for each entry where there are multiple locations. In the case of Virginia, there is only one entry, so the row turns out fine.

It almost seems like I need to do another pivot or something. Can anyone offer advice on where I'm going wrong?

Sorry. The desired output should look like so:

Location | Apple | apple_comments | Orange | Orange_comments | Pear | Pear_comments
Tennessee | 0 | NULL | 1 | very juicy | 1 | NULL
Florida | 1 | crisp | 1 | NULL | 0 | NULL
Virginia | 0 | NULL | 1 | NULL | 1 | tasty

Essentially, merging the duplicates into one row.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别想她 2024-12-16 15:18:24

根本问题是,您实际上已经告诉编译器除了 food 列之外,还按 comment 列进行分组。有一些解决方案,例如将评论汇总到分隔列表中,如下所示:

Select location
    , Sum( Case When S.food = 'Apple' Then 1 Else 0 End ) As Apple
    , Stuff(
        (
        Select ', ' + S1.Apple_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Apple_Comments Is Not Null
        Group By S1.Apple_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Apple_Comments
    , Sum( Case When S.food = 'Orange' Then 1 Else 0 End ) As Orange
    , Stuff(
        (
        Select ', ' + S1.Orange_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Orange_Comments Is Not Null
        Group By S1.Orange_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Orange_Comments
    , Sum( Case When S.food = 'Pear' Then 1 Else 0 End ) As Pear
    , Stuff(
        (
        Select ', ' + S1.Pear_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Pear_Comments Is Not Null
        Group By S1.Pear_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Pear_Comments
From SomeTable As S
Group By S.location

The fundamental problem is that you have effectively told the compiler to group by the comment column in addition to the food column. There are some solutions such as rolling up the comments into a delimited list like so:

Select location
    , Sum( Case When S.food = 'Apple' Then 1 Else 0 End ) As Apple
    , Stuff(
        (
        Select ', ' + S1.Apple_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Apple_Comments Is Not Null
        Group By S1.Apple_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Apple_Comments
    , Sum( Case When S.food = 'Orange' Then 1 Else 0 End ) As Orange
    , Stuff(
        (
        Select ', ' + S1.Orange_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Orange_Comments Is Not Null
        Group By S1.Orange_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Orange_Comments
    , Sum( Case When S.food = 'Pear' Then 1 Else 0 End ) As Pear
    , Stuff(
        (
        Select ', ' + S1.Pear_Comments
        From SomeTable As S1
        Where S1.location = S.location
            And S1.Pear_Comments Is Not Null
        Group By S1.Pear_Comments
        For Xml Path(''), type
        ).value('.','nvarchar(max)')
        , 1, 2, '') As Pear_Comments
From SomeTable As S
Group By S.location
私藏温柔 2024-12-16 15:18:24

找到答案(利用“with CTE”和 MAX 函数):

;With CTE as (
SELECT PivotTable.location, [apple], [apple_comments], [orange], [orange_comments], [pear], [pear_comments]
FROM
(SELECT location, food, apple_comments, orange_comments, pear_comments FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable)
select location, MAX([apple]) as [apple], MAX([apple_comments]) as [apple_comments],MAX([orange]) as [orange], 
MAX([orange_comments]) as [orange_comments], MAX([pear]) as [pear], MAX([pear_comments]) as [pear_comments]
from CTE group by location

Found the answer (utilizes the 'with CTE' and MAX functions):

;With CTE as (
SELECT PivotTable.location, [apple], [apple_comments], [orange], [orange_comments], [pear], [pear_comments]
FROM
(SELECT location, food, apple_comments, orange_comments, pear_comments FROM someTable) as inventory
PIVOT
(COUNT(inventory.food) FOR inventory.location IN ([apple],[orange],[pear])) AS PivotTable)
select location, MAX([apple]) as [apple], MAX([apple_comments]) as [apple_comments],MAX([orange]) as [orange], 
MAX([orange_comments]) as [orange_comments], MAX([pear]) as [pear], MAX([pear_comments]) as [pear_comments]
from CTE group by location
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文