交叉表查询从表中获取最后日期的价格

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

我有三张桌子:

Table of Person

产品组

Table of ProductGroup

有日期的人员每个产品组的价格

Pricing

我想要以下结果来获取每个产品组最后日期的价格

Table of Result

请帮助我。

我通过创建表格然后逐个单元格设置来获取结果

但我想在一个查询中得到这个

sql sql-server pivot-table
2个回答
0
投票

有关为每个

Price
ProductGroupID
组合选择最新
PersonID
的逻辑,请参阅获取每组的前 1 行。一般技术是使用
ROW_NUMBER()
窗口函数 对每组内的行进行编号,然后筛选 row-number = 1。

完成后,只需执行 PIVOT 操作即可。

SELECT PVT.[GROUP C], PVT.[GROUP B], PVT.[GROUP A], PVT.FullName, PVT.PersonId
FROM (
    SELECT PG.ProductGroupName, PGP.Price, P.FullName, P.PersonId
    FROM (
        SELECT
            *,
            ROW_NUMBER()
                OVER(PARTITION BY ProductGroupID, PersonID ORDER BY PriceDate DESC)
                AS RowNum
        FROM ProductGroupPrice
    ) PGP
    JOIN ProductGroup PG
        ON PG.ProductGroupID = PGP.ProductGroupID
    JOIN person P
        ON P.PersonID = PGP.PersonID
    WHERE PGP.RowNum = 1
) Q
PIVOT (
    MAX(Q.Price)
    FOR Q.ProductGroupName IN ([GROUP C], [GROUP B], [GROUP A])
) PVT
ORDER BY PVT.PersonId

使用

PIVOT
的替代方法是 条件聚合,您可以在其中定义像
MAX(CASE WHEN <condition> THEN <value> END) AS <column>
这样的选择项。

SELECT
    MAX(CASE WHEN PG.ProductGroupName = 'GROUP C' THEN PGP.Price END) AS [GROUP C],
    MAX(CASE WHEN PG.ProductGroupName = 'GROUP B' THEN PGP.Price END) AS [GROUP B],
    MAX(CASE WHEN PG.ProductGroupName = 'GROUP A' THEN PGP.Price END) AS [GROUP A],
    P.FullName,
    P.PersonId
FROM (
    SELECT
        *,
        ROW_NUMBER()
            OVER(PARTITION BY ProductGroupID, PersonID ORDER BY PriceDate DESC)
            AS RowNum
    FROM ProductGroupPrice
) PGP
JOIN ProductGroup PG
    ON PG.ProductGroupID = PGP.ProductGroupID
JOIN person P
    ON P.PersonID = PGP.PersonID
WHERE PGP.RowNum = 1
GROUP BY P.FullName, P.PersonId
ORDER BY P.PersonId

中间结果:

产品组名称 价格 全名 人员ID
A组 250 卡雷尔 1
A组 120 阿里 3
A组 100 埃姆兰 4
B组 150 卡雷尔 1
B组 200 杰克 2
C组 150 卡雷尔 1
C组 100 杰克 2
C组 105 哈娜 5

最终结果:

C组 B组 A组 全名 人员ID
150 150 250 卡雷尔 1
100 200 杰克 2
120 阿里 3
100 埃姆兰 4
105 哈娜 5

请参阅 this db<>fiddle 了解两种方法的演示。


0
投票

您可以使用 PIVOT 来获取一次查询的结果

select 
     isnull(MAX([Group C]),'') as [Group C]
  ,  isnull(MAX([Group B]),'') as [Group B]
  ,  isnull(MAX([Group A]),'') as [Group A]
  ,FullName, PersonID
from
(
SELECT PGP.*, P.FullName, PG.ProductGroupName, CONVERT(varchar(10),Pricedate,112) + '-' + Price as DatePrice
FROM ProductGroupPrice PGP
INNER JOIN ProductGroup PG ON PG.ProductGroupID=PGP.ProductGroupID
INNER JOIN person P ON P.PersonID=PGP.PersonID
) x
pivot
(
  max(DatePrice)
  for ProductGroupName in([Group A], [Group B], [Group C])
)p
  GROUP BY FullName, PersonID

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.