道歉,如果这有点令人困惑,但希望有人可以帮助我。出于某种原因,我的想法在这上面留下了空白,并且输入问题可能有所帮助。
我正在做一些ETL的东西,我有可以按特定Id
值分组的数据。我的数据集中的每条记录都有一个LookupId
值,我用它来加入另一个表并获取其他信息。这里很标准INNER JOIN
。但是,我还需要在数据集中包含缺少的LookupId
值。这会将我的INNER JOIN
变成LEFT JOIN
,这也是非常标准的东西。
您可以使用以下示例架构和数据来了解我要做的事情:
-- Create sample schema
CREATE TABLE ETL_DataSet (
Id INT NOT NULL,
LookupId INT NULL,
LookupCode CHAR(1) NULL,
LookupDesc NVARCHAR(40) NULL
);
CREATE TABLE ETL_LookupTable (
LookupId INT NOT NULL
, LookupCode CHAR(1) NOT NULL
, LookupDesc NVARCHAR(40) NOT NULL
, CONSTRAINT PK_LookupTable_LookupId PRIMARY KEY CLUSTERED (LookupId)
);
-- Insert sampel data
INSERT INTO ETL_LookupTable (LookupId, LookupCode, LookupDesc) VALUES
(1, 'Z', 'Z Description'),
(2, 'A', 'A Description'),
(3, 'B', 'B Description'),
(4, 'C', 'C Description'),
(5, 'D', 'D Description'),
(6, 'E', 'E Description'),
(7, 'X', 'X Description');
INSERT INTO ETL_DataSet (Id, LookupId, LookupCode, LookupDesc) VALUES
(1, 3, 'B', 'B Description'),
(1, 5, 'D', 'D Description'),
(1, 3, 'B', 'B Description'),
(1, 2, 'A', 'A Description'),
(2, 4, 'C', 'C Description'),
(2, 6, 'E', 'E Description'),
(2, 3, 'B', 'B Description'),
(2, 2, 'A', 'A Description');
以下是要运行的示例脚本:
DECLARE @id INT = 1; //change this to 1 or 2
;WITH LookupCTE AS
(
SELECT d.*
FROM ETL_LookupTable l INNER JOIN ETL_DataSet d ON l.LookupId = d.LookupId
WHERE d.Id = @id --comment this out to get all data in ETL_DataSet
)
SELECT *
FROM ETL_LookupTable l LEFT JOIN LookupCTE cte ON l.LookupId = cte.LookupId
最终目标是包括每个Id
的所有LookupTable值,即使这组ID没有LookupTable值。将@Id
更改为1到2之间您可以看到这是有效的,但如果您在CTE中注释掉WHERE
子句,则会得到不正确的数据。我试图在不使用游标或任何其他逐行排列技术的情况下这样做,所以希望有人可以帮助或指出我正确的方向。
所需结果应如下所示:
Id LookupId LookupCode LookupDesc
----------- ----------- ---------- ----------------------------------------
1 2 A A Description
1 3 B B Description
1 3 B B Description
1 NULL C C Description
1 5 D D Description
1 NULL E E Description
1 NULL X X Description
1 NULL Z Z Description
2 2 A A Description
2 3 B B Description
2 4 C C Description
2 NULL D D Description
2 6 E E Description
2 NULL X X Description
2 NULL Z Z Description
答案 0 :(得分:2)
您似乎想要etl_dataset.id
的笛卡尔积和etl_lookupTable
信息,因此形成该产品的cross join
应该有效。
select ed.*, el.*, d.* from (select distinct id from etl_dataset) ed cross join (select distinct LookupId, LookupCode, LookupDesc from ETL_LookupTable) el left join etl_dataset d on ed.id = d.id and el.LookupId = d.LookupId order by ed.id, el.LookupCode GO
id | LookupId | LookupCode | LookupDesc | Id | LookupId | LookupCode | LookupDesc -: | -------: | :--------- | :------------ | ---: | -------: | :--------- | :------------ 1 | 2 | A | A Description | 1 | 2 | A | A Description 1 | 3 | B | B Description | 1 | 3 | B | B Description 1 | 3 | B | B Description | 1 | 3 | B | B Description 1 | 4 | C | C Description | null | null | null | null 1 | 5 | D | D Description | 1 | 5 | D | D Description 1 | 6 | E | E Description | null | null | null | null 1 | 7 | X | X Description | null | null | null | null 1 | 1 | Z | Z Description | null | null | null | null 2 | 2 | A | A Description | 2 | 2 | A | A Description 2 | 3 | B | B Description | 2 | 3 | B | B Description 2 | 4 | C | C Description | 2 | 4 | C | C Description 2 | 5 | D | D Description | null | null | null | null 2 | 6 | E | E Description | 2 | 6 | E | E Description 2 | 7 | X | X Description | null | null | null | null 2 | 1 | Z | Z Description | null | null | null | null
dbfiddle here
答案 1 :(得分:2)
CREATE TABLE #ETL_DataSet (
Id INT NOT NULL,
LookupId INT NULL,
LookupCode CHAR(1) NULL,
LookupDesc NVARCHAR(40) NULL
);
CREATE TABLE #ETL_LookupTable (
LookupId INT NOT NULL
, LookupCode CHAR(1) NOT NULL
, LookupDesc NVARCHAR(40) NOT NULL
, CONSTRAINT PK_LookupTable_LookupId PRIMARY KEY CLUSTERED (LookupId)
);
-- Insert sampel data
INSERT INTO #ETL_LookupTable (LookupId, LookupCode, LookupDesc) VALUES
(1, 'Z', 'Z Description'),
(2, 'A', 'A Description'),
(3, 'B', 'B Description'),
(4, 'C', 'C Description'),
(5, 'D', 'D Description'),
(6, 'E', 'E Description'),
(7, 'X', 'X Description');
INSERT INTO #ETL_DataSet (Id, LookupId, LookupCode, LookupDesc) VALUES
(1, 3, 'B', 'B Description'),
(1, 5, 'D', 'D Description'),
(1, 3, 'B', 'B Description'),
(1, 2, 'A', 'A Description'),
(2, 4, 'C', 'C Description'),
(2, 6, 'E', 'E Description'),
(2, 3, 'B', 'B Description'),
(2, 2, 'A', 'A Description');
select * from #ETL_DataSet
select * from #ETL_LookupTable
SELECT E.ID,D.LOOKUPID,E1.LOOKUPCODE,E1.LOOKUPDESC
FROM(
SELECT DISTINCT ID
FROM #ETL_DATASET) AS E
CROSS JOIN (SELECT * FROM #ETL_LOOKUPTABLE) AS E1
LEFT JOIN #ETL_DATASET D ON D.LOOKUPID = E1.LOOKUPID AND D.ID = E.ID
ORDER BY E.ID,E1.LOOKUPCODE,E1.LOOKUPDESC
输出
+----+----------+------------+---------------+
| ID | LOOKUPID | LOOKUPCODE | LOOKUPDESC |
+----+----------+------------+---------------+
| 1 | 2 | A | A Description |
| 1 | 3 | B | B Description |
| 1 | 3 | B | B Description |
| 1 | NULL | C | C Description |
| 1 | 5 | D | D Description |
| 1 | NULL | E | E Description |
| 1 | NULL | X | X Description |
| 1 | NULL | Z | Z Description |
| 2 | 2 | A | A Description |
| 2 | 3 | B | B Description |
| 2 | 4 | C | C Description |
| 2 | NULL | D | D Description |
| 2 | 6 | E | E Description |
| 2 | NULL | X | X Description |
| 2 | NULL | Z | Z Description |
+----+----------+------------+---------------+
答案 2 :(得分:1)
试试这个:
DECLARE @id INT = 2; --//change this to 1 or 2
;WITH IdList AS(
SELECT DISTINCT id FROM ETL_DataSet
), LookupCTE AS
(
SELECT IdList.id,d.LookupId, d.LookupCode, d.LookupDesc
FROM ETL_LookupTable l INNER JOIN IdList ON 1=1
LEFT JOIN ETL_DataSet d ON l.LookupId = d.LookupId AND d.id=IdList.id
-- WHERE d.Id = @id --comment this out to get all data in ETL_DataSet
)
SELECT * FROM LookupCTE --WHERE id=@id
1 NULL NULL NULL 1 2 A A Description 1 3 B B Description 1 3 B B Description 1 NULL NULL NULL 1 5 D D Description 1 NULL NULL NULL 1 NULL NULL NULL 2 NULL NULL NULL 2 2 A A Description 2 3 B B Description 2 4 C C Description 2 NULL NULL NULL 2 6 E E Description 2 NULL NULL NULL
答案 3 :(得分:0)
我认为你要找的结果应该将ETL_DataSet设置为左表。类似的东西:
SELECT * FROM ETL_DataSet LEFT JOIN ETL_LookupTable ON ETL_DataSet.LookupId = ETL_LookupTable.LookupId
参考:https://www.w3schools.com/sql/sql_join_left.asp
注意:LEFT JOIN关键字返回左表中的所有记录 ......,即使右表中没有匹配项。