MS SQL:嵌套选择 - 神秘的“无效列名”错误

发布于 2024-10-18 07:44:09 字数 921 浏览 0 评论 0原文

当我对 MSSQL 2000 运行以下查询时,

SELECT 
    DISTINCT(Email),
    (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptIn') optin,
    (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptOut') optout
FROM
    Activity a,
    Consumer c,
    ActivityType t
WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND optin > 1

出现以下错误

Server: Msg 207, Level 16, State 3, Line 1
Invalid column name 'optin'.

为什么会发生这种情况?我不明白为什么它会无效。

When I run the following query against a MSSQL 2000

SELECT 
    DISTINCT(Email),
    (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptIn') optin,
    (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptOut') optout
FROM
    Activity a,
    Consumer c,
    ActivityType t
WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND optin > 1

I get the following error

Server: Msg 207, Level 16, State 3, Line 1
Invalid column name 'optin'.

Why does this happen? I can't see why it would be invalid.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我是男神闪亮亮 2024-10-25 07:44:09

SQL Server 不允许您在同一级别通过名称引用别名。要解决此问题,请重复列定义:

WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptIn'
        ) > 1

或使用子查询:

SELECT  *
FROM    (
        SELECT 
            DISTINCT(Email),
            (...) optin,
            (...) optout
        FROM
            Activity a,
            Consumer c,
            ActivityType t
        ) as SubqueryAlias
WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND optin > 1

SQL Server does not allow you to refer to aliases by name at the same level. To fix this, repeat the column definition:

WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND (SELECT TOP 1 ActivityID
        FROM Activity aa, ActivityType tt 
        WHERE aa.ActivityTypeId = tt.ActivityTypeId 
            AND aa.ConsumerID = c.ConsumerID
            AND tt.ActivityType = 'Something_OptIn'
        ) > 1

Or use a subquery:

SELECT  *
FROM    (
        SELECT 
            DISTINCT(Email),
            (...) optin,
            (...) optout
        FROM
            Activity a,
            Consumer c,
            ActivityType t
        ) as SubqueryAlias
WHERE
    c.CountryID = '23'
    AND t.ActivityType = 'Something_Create'
    AND a.ActivityTypeId = t.ActivityTypeId
    AND c.ConsumerID = a.ConsumerID
    AND optin > 1
柏拉图鍀咏恒 2024-10-25 07:44:09

最后一行 AND optin > 1 是犯罪者。

WHERE 子句对 SELECT 列表中的列别名一无所知。

您可能应该在没有违规条件的情况下对此 SELECT 进行子查询,并将该条件应用于外部 SELECT。

SELECT *
FROM (
  SELECT
  ...
  WHERE ... /* everything except 'optin > 1' */
) anyAlias
WHERE optin > 1

The last line AND optin > 1 is the offender.

The WHERE clause knows nothing about column aliases in the SELECT list.

You should probably subquery this SELECT without the offending condition, and apply that condition to the outer SELECT.

SELECT *
FROM (
  SELECT
  ...
  WHERE ... /* everything except 'optin > 1' */
) anyAlias
WHERE optin > 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文