【问题标题】:metadata of pivotted field [closed]旋转字段的元数据[关闭]
【发布时间】:2016-02-14 01:30:24
【问题描述】:

我有一个基于复杂数据库设置的复杂问题。

我有一个包含 fieldId、objectId、fieldValue 的表。 每个对象在此表中有很多行 - 每个字段一行。

示例 - 有名字、出生日期、体重、身高、学校等字段

一个对象(id:1)可以有以下行:

1.1.'john'
1.2.'march-31-2000'
1.3.155
1.4.60
1.5.'ps 176'

我有一个网格,它将为每个字段显示一列,为每个对象显示一行 - 列名将是 firstName、dob、weight、height、school 我的数据库中的所有对象都会有行

我使用数据透视表来获取这些数据 -

类似-

SELECT *
  FROM #temp123
 PIVOT (
          MAX(fieldValue)
          FOR [Variable] IN ([firstName],[dob],[weight],[height],[school])
       ) AS p

这非常适合显示数据。但是,现在是时候将排序添加到我的网格中了。我希望 int 列像 int (101>99) 一样排序,日期列像日期一样显示 (1/1/2016>12/31/2015)

我怎样才能做到这一点。

谢谢!

【问题讨论】:

  • 也许您必须更好地解释那些仅出现在您的问题末尾的 INT 和 DATE 字段与其他所有内容无关。你能更好地解释一下吗?关于它的数据样本也很好。
  • 亲爱的 StackOverflow,您的社区由一些知识渊博且乐于助人的程序员组成,例如下面引用的 Shnugo,不幸的是,一些知识不丰富的无聊 ppl 喜欢用不相关和消极的 cmets 破坏许多问题。我发布了一个非常明确的问题,带有示例和详细信息,知识渊博的程序员能够给我很多帮助。见下文。后一类程序员只是试图给出不相关的负面反馈。例如 - “也许你必须更好地解释那些 INT 和 DATE 字段”。整数和日期字段实际上已经
  • 详细解释。你要我解释为什么学生 A 重 250 磅,学生 B 重 125 磅。你要我补充一下学生 A 比学生 B 吃得更多的细节吗?我开始觉得这些无关紧要的 cmets 幼稚可笑。我相信你应该对他们做点什么。
  • 这里不必粗鲁。我们都在这里提供帮助,永远记住这一点。您的问题已被五个阅读它并难以理解的人关闭。可以根据您的 观点进行解释。在这里,我们不假设一个人是否有经验。我们只是想确定数据,以便我们可以提供好的和准确的答案。至于您的“我发布了一个非常明确的问题”,这里是一个很好且格式正确的 SQL 问题的示例:meta.stackoverflow.com/a/271056/460557 如果您在结束您的问题时仍然觉得我们错了,您可以打开一个案例...
  • meta.stackoverflow.com这里有你投诉的地方。

标签: sql types datatable pivot


【解决方案1】:

这可能是您的解决方案:

CREATE TABLE #EntityAttributValue (entityID INT, Attribute VARCHAR(100),Value VARCHAR(100));
INSERT INTO #EntityAttributValue VALUES
 (1,'BirthDate','2000-04-01')
,(1,'Size','1.72')
,(1,'FirstName','John')
,(1,'LastName','Doe')
,(2,'BirthDate','1990-04-01')
,(2,'Size','1.81')
,(2,'FirstName','Jane')
,(2,'LastName','Miller')
,(3,'BirthDate','1980-05-01')
,(3,'FirstName','Hugo')
,(3,'LastName','Boss');

DECLARE @columns VARCHAR(MAX)=
(
    SELECT STUFF(
    (
    SELECT DISTINCT ',[' + Attribute + ']' 
    FROM #EntityAttributValue
    FOR XML PATH('')
    ),1,1,'')

);

DECLARE @query VARCHAR(MAX)=
'SELECT p.*
FROM
(
    SELECT *
    FROM #EntityAttributValue
) AS tbl
PIVOT
(
    MIN(Value) FOR Attribute IN(' + @columns + ')
) AS p';

--The column's list might be generated from metadata (dictionary attrib/type)
DECLARE @Wrapped VARCHAR(MAX)=
';WITH MyCTE AS (' +  @query + ')
SELECT  entityID
       ,CAST(BirthDate AS DATE) AS BirthDate
       ,FirstName
       ,LastName
       ,CAST(Size AS FLOAT) AS Size
FROM MyCTE';

EXEC (@Wrapped);

GO
DROP TABLE #EntityAttributValue;

这是以前的答案

名称-值-对(或实体-属性-值表 [EAV])通常是人们不应该做的事情......这里有一篇文章(你会发现更多!)描述原因:@ 987654321@

如果你必须坚持这个设计,有一个使用CASEGROUP BY 的解决方案,但你必须确定你的值将被正确转换(特别小心日期时间值!):

DECLARE @EntityAttributValue TABLE(entityID INT, Attribute VARCHAR(100),Value VARCHAR(100));
INSERT INTO @EntityAttributValue VALUES
 (1,'BirthDate','2000-04-01')
,(1,'Size','1.72')
,(1,'FirstName','John')
,(1,'LastName','Doe')
,(2,'BirthDate','1990-04-01')
,(2,'Size','1.81')
,(2,'FirstName','Jane')
,(2,'LastName','Miller')
,(3,'BirthDate','1980-05-01')
,(3,'FirstName','Hugo')
,(3,'LastName','Boss');

SELECT eav.entityID
      ,MAX(CASE WHEN eav.Attribute='FirstName' THEN eav.Value ELSE NULL END) AS FirstName
      ,MAX(CASE WHEN eav.Attribute='LastName' THEN eav.Value ELSE NULL END) AS LastName
      ,MAX(CASE WHEN eav.Attribute='BirthDate' THEN CAST(eav.Value AS DATE) ELSE NULL END) AS Birtdate
      ,MAX(CASE WHEN eav.Attribute='Size' THEN CAST(eav.Value AS FLOAT) ELSE NULL END) AS Size
FROM @EntityAttributValue AS eav
GROUP BY eav.entityID

【讨论】:

  • 我了解您对标准查询的评论,但我不知道如何在数据透视表中执行此操作 - SELECT * FROM #temp123 PIVOT ( MAX(fieldValue)--case 语句在这里不起作用 FOR [Variable ] IN ([firstName],[dob],[weight],[height],[school]) ) AS p
  • @thewhiz 不,这是代替PIVOT 枢轴将不允许您键入此内容。可能有机会包装您的完整查询(CTE 或子选择)并在最外面的SELECT 中输入完整的列列表并在那里进行强制转换......
  • 哦,我明白了。我动态生成这个查询,我可以有很多列。你知道支点是否比这更有效吗?或相反亦然?我绝对喜欢干净的枢轴语法,但也许这种方法是我需要采用的
  • @thewhiz,据我所知,这个“老式支点”在性能上更好......如果这解决了您的问题,那么在投票计数器下方打勾,谢谢!
  • 谢谢。我会这样做,但是您能否再澄清一件事-如果我想坚持使用老式的枢轴以获得更好的性能-我是否应该获得fieldID字典-fieldType以及非文本字段,请转换那么列呢?
猜你喜欢
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 2020-10-29
  • 1970-01-01
相关资源
最近更新 更多