Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将名称-值表转换为另一个名称作为列标题的表,但一种名称类型可以有多个值_Sql_Sql Server_Pivot - Fatal编程技术网

Sql 将名称-值表转换为另一个名称作为列标题的表,但一种名称类型可以有多个值

Sql 将名称-值表转换为另一个名称作为列标题的表,但一种名称类型可以有多个值,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有以下表格结构: 结构-1 我想将此结构转换为以下内容: 中间结构 我已经尝试过使用PIVOT/CrossTab,但是我不能使用聚合函数,因为这里没有可聚合的内容。我也尝试过CASE表达式,但我不希望Cat1、Cat2和Cat3列中出现4行null,因为它们没有任何值。若我用一个聚合函数来表示CASE,那个么我只得到CAT3列的一个值 我认为我使用的解决方案结构可能不准确,因为它是我试图构建的查询的中间结果 我有另一个结构-2,我需要加入结构-1,如下所示: +-------+--------

我有以下表格结构:

结构-1

我想将此结构转换为以下内容:

中间结构

我已经尝试过使用PIVOT/CrossTab,但是我不能使用聚合函数,因为这里没有可聚合的内容。我也尝试过CASE表达式,但我不希望Cat1、Cat2和Cat3列中出现4行null,因为它们没有任何值。若我用一个聚合函数来表示CASE,那个么我只得到CAT3列的一个值

我认为我使用的解决方案结构可能不准确,因为它是我试图构建的查询的中间结果

我有另一个结构-2,我需要加入结构-1,如下所示:

+-------+------------+--------+
| Rule  | CategoryId | ItemId |
+-------+------------+--------+
| Rule1 | Cat1       |      1 |
| Rule1 | Cat2       |      6 |
| Rule2 | Cat1       |      1 |
| Rule2 | Cat2       |      6 |
| Rule2 | Cat3       |      5 |
| Rule2 | Cat3       |     50 |
+-------+------------+--------+
因此,如果我看一下规则1和规则2,那么只有规则2应该适用于符号代码212374,因为它符合确切的标准,仅此而已


我可以构建什么样的查询来实现这一点?

对于这个非常具体的情况,您可以这样做:

declare @t table (symbolcode int,category varchar(10),itemid int)
insert into @t (symbolcode,category,itemid)values (212374,'cat1',1)
insert into @t (symbolcode,category,itemid)values (212374,'cat2',6)
insert into @t (symbolcode,category,itemid)values (212374,'cat3',5)
insert into @t (symbolcode,category,itemid)values (212374,'cat3',60)

;WITH CTE AS(
select symbolcode,cat1,cat2,cat3
from
(
  select symbolcode, category,itemid
  from @t
) d
pivot
(
  max(itemid)
  for category in (cat1,cat2,cat3)
) piv
)
,CTE2 AS
(select symbolcode,cat1,cat2,cat3
from
(
  select symbolcode, category,itemid
  from @t
) d
pivot
(
  MIN(itemid)
  for category in (cat1,cat2,cat3)
) piv)

select * from CTE
UNION 
select * from CTE2
SELECT
  SymbolCode
, (SELECT TOP 1 ItemId FROM MyTable WHERE CategoryId='Cat1' AND SymbolCode=mt.SymbolCode) AS Cat1
, (SELECT TOP 1 ItemId FROM MyTable WHERE CategoryId='Cat2' AND SymbolCode=mt.SymbolCode) AS Cat2
, ItemId AS Cat3
FROM MyTable mt
WHERE CategoryId='Cat3'

您仍然可以使用聚合函数来透视数据,您只需要一些独特的东西来允许返回多行。对于您的情况,我会使用一个窗口功能,如row_number。这将为每个符号代码CategoryID创建一个唯一的序列-然后在为聚合进行分组时使用该数字

您将从类似以下内容的查询开始:

select  
  s1.SymbolCode,
  s1.CategoryID,
  s2.ItemId,
  seq = row_number() over(partition by s1.symbolcode, s1.categoryid 
                          order by s1.itemid)
from Structure1 s1
inner join Structure2 s2
  on s1.categoryid = s2.categoryid
  and s1.ItemId = s2.ItemId
看。这给出了以下结果:

| SYMBOLCODE | CATEGORYID | ITEMID | SEQ |
|------------|------------|--------|-----|
|     212374 |       Cat1 |      1 |   1 |
|     212374 |       Cat1 |      1 |   2 |
|     212374 |       Cat2 |      6 |   1 |
|     212374 |       Cat2 |      6 |   2 |
|     212374 |       Cat3 |      5 |   1 |
|     212374 |       Cat3 |     50 |   2 |
| SYMBOLCODE | CAT1 | CAT2 | CAT3 |
|------------|------|------|------|
|     212374 |    1 |    6 |    5 |
|     212374 |    1 |    6 |   50 |
现在您有了一个seq列,其中包含每组符号代码CategoryId的唯一编号。获得此值后,可以将数据透视到列中:

select SymbolCode,
  Cat1 = max(case when categoryid = 'Cat1' then itemid end),
  Cat2 = max(case when categoryid = 'Cat2' then itemid end),
  Cat3 = max(case when categoryid = 'Cat3' then itemid end)
from
(
  select  
    s1.SymbolCode,
    s1.CategoryID,
    s2.ItemId,
    seq = row_number() over(partition by s1.symbolcode, s1.categoryid 
                            order by s1.itemid)
  from Structure1 s1
  inner join Structure2 s2
    on s1.categoryid = s2.categoryid
    and s1.ItemId = s2.ItemId
) d
group by symbolcode, seq;
看。这给出了以下的最终结果:

| SYMBOLCODE | CATEGORYID | ITEMID | SEQ |
|------------|------------|--------|-----|
|     212374 |       Cat1 |      1 |   1 |
|     212374 |       Cat1 |      1 |   2 |
|     212374 |       Cat2 |      6 |   1 |
|     212374 |       Cat2 |      6 |   2 |
|     212374 |       Cat3 |      5 |   1 |
|     212374 |       Cat3 |     50 |   2 |
| SYMBOLCODE | CAT1 | CAT2 | CAT3 |
|------------|------|------|------|
|     212374 |    1 |    6 |    5 |
|     212374 |    1 |    6 |   50 |

为什么需要在第二行中重复Cat11、Cat2值?为什么不直接使用null呢?如果Cat1或Cat2有多个ItemId呢?我们可以选择max或min Why值重复@darsin@TabAlleman我同意你的观点,但这是我正在处理的一个非常具体的案件。对于您指出的情况,我认为我提供的解决方案结构将失败。@Darsin您没有解释为什么需要重复Cat1或Cat2的值?您是否只有2个Cat3值?@darsin您是否可以检查更新的查询,因为它根据您所需的数据进行了修改