在查询(和子查询)之间共享值

时间:2014-12-30 09:56:10

标签: sql teradata

我正在尝试创建一个需要在子查询上进行连接的查询。但是,我还需要能够通过主查询的结果限制子查询的结果。

我修改了上一个问题,以显示我想要运行的完整“概念”查询。我知道它会充满问题,但是我缺乏足够的语法来修改语法以使这个查询运行。

以下示例:

    SELECT
    w.timestamp,
    c.timestamp
FROM
    table1 w
FULL OUTER JOIN
    (SELECT
            customer_id,
            timestamp
        FROM
            table1 c
        HAVING
            c.timestamp < w.timestamp
        AND
            timestamp = MAX(c.timestamp)) c
ON
    w.customer_id = c.customer_id
WHERE
    payment_type_code='WithdrawPayment'
AND
    w.customer_id IN
        (SELECT
            customer_id,
            timestamp
        FROM
            table1
        WHERE
            c.timestamp < w.timestamp
        AND
            timestamp = MAX(c.timestamp)
    ORDER BY
            c.timestamp DESC
        )
HAVING
    (SELECT 
        COUNT(*)
    FROM
         table1 u
    WHERE
        u.timestamp > c.timestamp
    AND
        u.timestamp < w.timestamp) u > 0
;

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

正如评论中提到的其他人一样,您的查询存在完全缺陷:您无法同时访问聚合数据和详细数据,也无法与派生表中的查询相关联。

但你似乎在table1中的table2之前寻找table2中的最大时间戳,这可以表示如下:

SELECT
    w.timestamp,
    c.timestamp
FROM
    table1 w
LEFT JOIN
    table1 c
ON
    w.customer_id = c.customer_id -- join on customer_id
AND c.timestamp < w.timestamp     -- using only earlier timestamps
WHERE
    action_type ='type1'
QUALIYF
    RANK()
    OVER (PARTITION BY w.customer_id -- assuming there's only one row per customer in w
          ORDER BY c.timestamp DESC) = 1 -- find the maximum timestamp

答案 1 :(得分:0)

您的查询不是有效的SQL,甚至不清楚您要使用它实现的目标。 (我必须承认我甚至没有猜到你的查询的目的。)你应该告诉我们查询应该做什么,而不是要求我们指出你的语法错误。

无论如何,让我们从您的派生表开始:

SELECT customer_id, timestamp
FROM table1 c
HAVING c.timestamp < w.timestamp
AND timestamp = MAX(c.timestamp)

您正在选择table1记录(仅限于customer_id和timestamp列)。您正在选择所有行(没有WHERE子句)。然后有一个HAVING子句。这在这里无效。在聚合值之后,HAVING子句起作用,例如如果您选择MIN(customer_id)和MAX(时间戳)作为一个记录或每个组(使用GROUP BY)。就像你的HAVING条款毫无意义一样,我真的很想知道你是如何使用它的。

然后在HAVING子句中将时间戳与MAX(时间戳)进行比较。你不能这样做。聚合时有一段时间,例如,您可以查看记录及其时间戳列。然后在聚合后有一段时间,你可以看一下MAX(时间戳)。你不能同时看到它们。为此,您必须从同一个表中选择两次,一次查看单个记录,一次查看聚合。如:

SELECT customer_id, timestamp
FROM table1 c
WHERE timestamp = (select MAX(timestamp) from table1)

在这里,我检查每条记录,它的时间戳是否等于表的最大时间戳,只保留那些记录。

此外,您正在访问此处不可见的w.timestamp。您只能比较派生表查询之外的时间戳:

FROM table1 w
FULL OUTER JOIN
(
  SELECT customer_id, timestamp
  FROM table1
  WHERE timestamp = (select MAX(timestamp) from table1)
) c ON c.timestamp = w.timestamp

最后你正在做一个完整的外部联接。为什么? X FULL OUTER JOIN Y保留Y中不可用的X记录,反之亦然。但是,您选择FROM table1 w,以便从table1获取所有记录并使用table1的子集(您的派生表查询)进行连接。因此,派生表中的记录不能与table1中的匹配。因此,完整的外部联接完全没有意义。然后在你的查询的WHERE子句中,你要求某个w.customer_id。如果外连接工作,您将获得w.customer_id为null的组成记录。您的WHERE子句将删除这些。你的完全外连接没有任何意义的另一个原因。

还有什么?那么你问w.customer_id IN (SELECT customer_id, timestamp FROM ...)。这在语法上是错误的。单个值w.customer_id永远不会匹配值对customer_id, timestamp。您可以改为w.customer_id IN (SELECT customer_id FROM ...)

然后在您的主查询中再次使用HAVING,尽管没有完成聚合。

我认为如果你练习非常基本的查询会很好。使用WHERE的查询。带聚合的查询,比如MAX。每个组具有聚合的查询(即使用GROUP BY)。具有聚合和HAVING子句的查询。带有WHERE子句的HAVING子句的查询...

关于你的查询:也许我上面说的可以帮助你逐步建立它。如果没有,请回来告诉我们您的查询应该做什么,我们会告诉您如何做。