SQL 主查询子查询中 WHERE 中使用的值

Jef*_*son 1 sql-server subquery

我真的对这里的 SQL 感到困惑,我有这个示例,其中我在子查询中使用主查询的值,然后使用 XML PATH 在日期之间添加逗号。设置是两张表,其中一张是我想要串在一起的日期。我不确定为什么子查询 where 语句没有重新调整正确的结果。

http://www.sqlfiddle.com/#!5/5443b/2

设置

CREATE TABLE log
    ([logID] [int] NULL, 
     [LogDate] [datetime] NULL
    )
;

CREATE TABLE logdata
    ([logdataID] [int] NULL, 
     [logID] [datetime] NULL
    )
;
    
INSERT INTO log
    ([logID], [LogDate])
VALUES
    (1, 2021-02-01),
    (1, 2021-02-02),
    (1, 2021-02-03),
    (3, 2021-03-12),
    (4, 2021-02-12)
;

INSERT INTO logdata
    ([logdataID], [logID])
VALUES
    (1, 1),
    (2, 2),
    (3, 3)
;
Run Code Online (Sandbox Code Playgroud)

我的尝试:

Select 
logID,
logdataID
LogDate =  (SELECT ',' + CAST(LogDate AS varchar) FROM log WHERE logID =  logID FOR XML PATH('') )
from logdata
Run Code Online (Sandbox Code Playgroud)

结果

1,2021-02-01,2021-02-02,2021-02-03,2021-03-12,2021-02-12
2,2021-02-01,2021-02-02,2021-02-03,2021-03-12,2021-02-12
3,2021-02-01,2021-02-02,2021-02-03,2021-03-12,2021-02-12
Run Code Online (Sandbox Code Playgroud)

但我想要的结果是:

1 2021-02-01,2021-02-02,2021-02-03
2 2021-03-12
3 2021-02-12
Run Code Online (Sandbox Code Playgroud)

AMt*_*two 6

在你的子查询中,WHERE logID = logID是不明确的。LogID 存在于两个表中,但查询不会告诉 SQL Server 您打算使用logID一个表中的数据来连接到logID另一个表中的数据。

在您的查询版本中,SQL Server 仅在子查询的范围内解释该内容,因此它使用的log.logID = log.logID本质上是说WHERE 1=1.

相反,始终使用表别名并在列前加上表别名。像这样的东西:

SELECT 
    ld.logID,
    ld.logdataID,
    LogDate =  (SELECT ',' + CAST(l.LogDate AS varchar) 
                FROM log AS l 
                WHERE l.logID =  ld.logID 
                FOR XML PATH('') 
               )
FROM #logdata AS ld;
Run Code Online (Sandbox Code Playgroud)