【问题标题】:Normalizing data through a query/SQL (standard normal), and nested subqueries通过查询/SQL(标准正常)和嵌套子查询规范化数据
【发布时间】:2013-06-20 21:18:30
【问题描述】:

好的,所以我有一个包含一堆(相对)正态分布的表。为简洁起见,有 3 个字段。外键、X 值和 Y 值。为简单起见,我们将 x 和 y 称为 FieldX 和 FieldY,以及键 SampleID。

所以我想要 6000 条具有相同 SampleID 的记录,这将是一个单一的正态分布,并且我有大约 20 个分布(所以总共有 120k 条记录,给予或接受)。

现在,我需要做的是将数据标准化为所谓的“标准正态”形式,这意味着它们的最大峰值都排成一行。在 Excel 中,这没问题,但我必须使用 SQL 来完成。首先,我整理了一系列 3 个堆叠查询来解决这个问题:

Query1) 按 SampleID 求解 Max(FieldY) 组为 MaxFieldY(20 个结果)

Query2) 求解 FieldX,其中 FieldY == MaxFieldY.Query1 as MaxFieldX group by SampleID(20 个结果)

Query3) 通过 AdjFieldX 求解 FieldX-MaxFieldX + 100,000 作为 AdjFieldX 组(6k * 20 个结果)

这使得所有正态分布都以 100,000 为中心(我实际上不能像在真正的标准正态中那样以 0 为中心,因为这些曲线更符合对数正态并以对数刻度显示)。

这行得通。但是它的 3-stacked 查询,我必须为 6 种曲线执行此操作。那是 18 个静态/堆叠查询。我已经建立了一个庞大的数据库,而不必使用单个静态查询,并且我计划保持这种方式。在我的屏幕左侧看到一个查询对我来说是一个巨大的耻辱,我不会接受 18!

所以我需要在单个查询中执行此操作。我以前搞过子查询,有一次我对一些子查询做了一个非常丑陋的数字积分。很有意思。无论如何,在出现了一些令人惊讶的错误之后,我想出了以下几点:

SELECT
  TData.SampleID,
  TData.FieldY,
  (TData.FieldX - qMaxAdj.MaxFieldX+100000) AS Adj_FieldX
FROM 
(
  SELECT
    qMax.SampleID,
    TData.FieldX AS MaxFieldX,
    TData.FieldY 
  FROM 
  (
    SELECT
      TDataDupe.SampleID,
      max(TDataDupe.FieldY) AS MaxofFieldY
    FROM TData AS TDataDupe 
    GROUP BY TDataDupe.SampleID
  ) AS qMax 
  LEFT JOIN TData ON qMax.SampleID = TData.SampleID
  WHERE ((TData.FieldY)= qMax.MaxOfFieldY))
) AS qMaxAdj 
LEFT JOIN TData ON qMaxAdj.SampleID = TData.SampleID;

好的。是的。那是一张只有母亲才能爱的脸。你有几个问题在玩。 qMax 找到字段 Y 的最大值。然后将其连接回 qMaxAdj,后者确定 FieldY 最大值处的 FieldX 值,然后最后沿 x 进行归一化。

这行得通(不完全确定为什么,但确实如此),到目前为止性能还不错。但这真的很丑,而且我听说过嵌套子查询的坏事。此外,我没有真正接受过编写 SQL 的培训,而且我很确定我在某个地方搞砸了,例如,我不知道为什么我没有在其中一个嵌套连接中使用 TData 别名就逃脱了(刚刚注意到这一点) .

让我感到震惊的是,这是一个如此简单的想法。我只需要通过 Max(Y) 处的 X 值来调整 X 值。一定有更好的方法。如果没有更好的方法,是否有更清洁的方法来编写这些子查询?或者有什么我需要注意性能方面的事情吗?

所以我来了,我是一个自学过的 SQL 黑客,希望找到一种更好的方法来实现更环保的领域。任何想法 Stack Overflow Kenobe?你是我唯一的希望。

(哦,是的,这是 MS Access 2010,我认为是 Jet 引擎)

【问题讨论】:

  • 提供您拥有的数据的小样本以及您希望如何调整它可能会有所帮助,我通读了它并认为我了解您所追求的,但有些数据价值一千词。
  • 真正描述它的最佳方式是我有一些正态曲线的数据,我想将它们切换为标准正态形式。这通常是通过分布的平均值来完成的,但由于这些并不是真正正常的,我需要通过模式(人口的最大点)来做到这一点。我需要将曲线的 x 变量移动一个等于 max(y 变量) 处的 x 值的量。

标签: sql ms-access ms-access-2010


【解决方案1】:

查找 MAX(FieldY) 的查询非常简单

SELECT SampleID, MAX(FieldY) AS MaxofFieldY
FROM TData 
GROUP BY SampleID

查找每个 SampleID 对应的 FieldX 值的查询是

SELECT t1.SampleID, MAX(t1.FieldX) AS MaxofFieldX
FROM 
    TData t1
    INNER JOIN
    (
        SELECT SampleID, MAX(FieldY) AS MaxofFieldY
        FROM TData 
        GROUP BY SampleID
    ) t2
        ON t1.FieldY=t2.MaxofFieldY
GROUP BY t1.SampleID

现在,“规范化”数据的查询将是

SELECT 
    t3.SampleID, 
    t3.FieldY,
    (t3.FieldX - t4.MaxofFieldX + 100000) AS Adj_FieldX
FROM
    TData t3
    INNER JOIN
    (
        SELECT t1.SampleID, MAX(t1.FieldX) AS MaxofFieldX
        FROM 
            TData t1
            INNER JOIN
            (
                SELECT SampleID, MAX(FieldY) AS MaxofFieldY
                FROM TData 
                GROUP BY SampleID
            ) t2
                ON t1.FieldY=t2.MaxofFieldY
        GROUP BY t1.SampleID
    ) t4
        ON t3.SampleID=t4.SampleID

请注意,每个步骤只是将上一步中的查询合并为派生表(分别别名为 t2t4)。

【讨论】:

  • 那么内连接和子查询有什么区别呢?内部连接是否更清洁?我想你也避免了这些左连接。
  • @user2125055 我被告知加入派生表比使用子查询更有效,但这并不是我发布答案的真正原因。我只是逐步构建解决方案,最终结果看起来比你所拥有的更“整洁”。 (我也没有刻意避免任何外连接,结果我似乎不需要它们。)
猜你喜欢
  • 2010-11-02
  • 1970-01-01
  • 2011-10-07
  • 2017-05-09
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2012-12-25
相关资源
最近更新 更多