【问题标题】:Difficult Grouping Query困难分组查询
【发布时间】:2013-01-10 15:57:11
【问题描述】:

我无法编写查询以获得我想要的结果。我有下表:

CREATE TABLE [dbo].[inputs](
    [iid] [int] IDENTITY(1,1) NOT NULL,
    [tag_id] [int] NULL,
    [date_time] [datetime] NULL,
    [input_raw] [float] NULL,
    [input_calibrated] [float] NULL,
    [input_type] [varchar](50) NULL,
    [virtual_record] [varchar](50) NULL,
    [status_change] [varchar](50) NULL,
    [prev_stat_chg] [varchar](50) NULL,
    [prev_status_change] [varchar](50) NULL,
    [unix_timestamp] [float] NULL,
 CONSTRAINT [PK_inputs] PRIMARY KEY CLUSTERED 
(
    [iid] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,   ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]`
)

我正在编写查询以获取可与我拥有的时间线图一起使用的格式的数据。需要数据“分组依据”“unix_timestamp”和“n”个 tag_id 的“input_raw”。

例如:

SELECT TOP 20 inputs.unix_timestamp, inputs.input_raw, inputs.tag_id 
FROM [200030].[dbo].inputs
WHERE inputs.tag_id = 92149 or inputs.tag_id = 92164
ORDER BY unix_timestamp DESC

给我结果:

unix_timestamp  input_raw   tag_id
1357788990  313         92149
1357788990  210         92164
1357788690  313         92149
1357788690  210         92164
1357788390  313         92149
1357788390  210         92164
1357788090  313         92149
1357788090  210         92164
1357787790  313         92149
1357787790  210         92164
1357787490  313         92149
1357787490  210         92164
1357787190  313         92149
1357787190  210         92164
1357786890  313         92149
1357786890  210         92164
1357786590  313         92149
1357786590  210         92164
1357786290  313         92149
1357786290  210         92164

我需要一个看起来像这样的结果:

unix_timestamp     tag(92149)     tag(92164)
1357788990         313            210
1357788690         313            210
|
|
Vetc...

如果时间戳上有其他标签的任何其他数据,则如果一个标签中缺少任何数据,则还需要字符串“未定义”或“NULL”。

有什么帮助吗?

【问题讨论】:

    标签: sql sql-server group-by pivot


    【解决方案1】:

    这是数据的枢纽。您没有指定您使用的 RDBMS,但您可以在所有数据库中使用以下内容:

    SELECT unix_timestamp,
      max(case when inputs.tag_id = 92149 then input_raw else null end) tag_92149,
      max(case when inputs.tag_id = 92164 then input_raw else null end) tag_92164
    FROM [200030].[dbo].inputs
    GROUP BY unix_timestamp
    

    SQL Fiddle with Demo

    如果您使用的是带有PIVOT 函数的数据库(SQL Server/Oracle),那么您可以使用:

    select *
    from
    (
      select unix_timestamp,
        input_raw,
        tag_id 
      from [200030].[dbo].inputs
    ) src
    pivot
    (
      max(input_raw)
      for tag_id in ([92149], [92164])
    ) piv
    

    SQL Fiddle with Demo

    两者的结果是:

    | UNIX_TIMESTAMP | 92149 | 92164 |
    ----------------------------------
    |     1357786290 |   313 |   210 |
    |     1357786590 |   313 |   210 |
    |     1357786890 |   313 |   210 |
    |     1357787190 |   313 |   210 |
    |     1357787490 |   313 |   210 |
    |     1357787790 |   313 |   210 |
    |     1357788090 |   313 |   210 |
    |     1357788390 |   313 |   210 |
    |     1357788690 |   313 |   210 |
    |     1357788990 |   313 |   210 |
    

    【讨论】:

    • 完美的每个人都给出了正确的答案,但这是最接近我需要的。我添加了“WHERE tag_id = 92149 或 tag_id = 92164”,所以我不会从数据库中的数千个其他标签中得到 NULL 结果。第二部分是我有一个 tag_id 绑定到的标签表。一个字段是“反转”的,这是一个标志“翻转”数据以进行绘图。您是否推荐一个触发器来进行数学运算,或者是否有一个 JOIN 或我可以用来包含每个 tag_id 的反转字段的东西。 tag_id 是两个表之间的 PK->FK。
    • @KevinKent 乐于助人。你用的是什么数据库?
    • 如果您要问的话,我们正在使用 mssql。
    • @KevinKent 我不完全理解您评论的第二部分。听起来你可以加入,但如果没有更多细节,那就很难了。
    • table 标签包含关于每个标签的更详细的数据。输入表仅用于历史数据,即图表/报告。来自输入的 tag_id 与 tags.tag_id 相关联。标签内是一个称为“反转”的字段。这是一个标志,指示进入输入表的数据是否需要“翻转”,即 abs(1-input_raw)。我想做这个 sql 端而不是 php 端。如果我的评论仍然令人困惑,我深表歉意。
    【解决方案2】:

    这是一个旋转查询。您可以在任何数据库中使用:

    select unix_timestamp, 
           max(case when tag = 92149 then input_raw end) as tag_92349,
           max(case when tag = 92164 then input_raw end) as tag_92164
    from (SELECT TOP 20 inputs.unix_timestamp, inputs.input_raw, inputs.tag_id 
         FROM [200030].[dbo].inputs
         WHERE inputs.tag_id = 92149 or inputs.tag_id = 92164
        ) t
    group by unix_timestamp
    ORDER BY unix_timestamp DESC
    

    【讨论】:

      【解决方案3】:
      SELECT  unix_timestamp,
              MAX(CASE WHEN tag = 92149 THEN input_raw ELSE NULL END) [tag92149],
              MAX(CASE WHEN tag = 92164 THEN input_raw ELSE NULL END) [tag92164]
      FROM    tableName
      GROUP BY unix_timestamp
      

      SELECT unix_timestamp, [92149] As tag92149, [92164] as tag92164
      FROM
          (
            SELECT    unix_timestamp, 
                      tag,
                      input_raw
            FROM      tableName
          ) a
          PIVOT
          (
            MAX(input_raw)
            for tag in ([92149], [92164])
          ) b
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-30
        • 1970-01-01
        • 2017-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        相关资源
        最近更新 更多