1

好的,所以我有一个包含一堆(相对)正态分布的表。为简洁起见,有 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 引擎)

4

1 回答 1

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)。

于 2013-06-21T17:17:13.513 回答