题
我得到了一些帮助来创建查询来解决我遇到的问题,解决方案似乎是创建两个 CTE,然后连接并查询它们。
如果我将两个 CTE 作为单个查询运行,每个表都包含预期的数据,但联接产生的结果少于应有的结果,并且存在重复项,甚至具有三个或更多重复项的行。
;WITH CTE1 AS
(
SELECT FContainerHylla.Name, FContainerPlats.HyllId,
FContainerPlats.x, FContainerPlats.y,
FContainerPlats.enable, FContainerHylla.Type,
ISNULL((SELECT MIN(fcontainer.id) AS id
FROM FContainer
WHERE (PlatsId = FContainerPlats.id)), 0) AS FcId
FROM FContainerPlats
INNER JOIN FContainerHylla ON FContainerPlats.HyllId =
FContainerHylla.Id
WHERE (FContainerHylla.Type IN (1, 6, 10))
),
CTE2 AS
(
SELECT FContainer.id AS SubID, produkter.Produktnamn AS Produktnamn
from FContainer
INNER JOIN Stämplingar ON FContainer.id = Stämplingar.ID
INNER JOIN Tempo ON Stämplingar.temponr = Tempo.temponr
INNER JOIN Produkter ON Tempo.produktnr = Produkter.Produktnr
)
SELECT CTE1.*, CTE2.Produktnamn
FROM CTE1
INNER JOIN CTE2 ON CTE2.SubID = CTE1.FcId
ORDER BY CTE1.HyllId, CTE1.x, CTE1.y
CTE1 生成一个大约 2600 行长的表,我已经验证它是正确的。CTE2 大约有 7000 条记录长并且也是正确的。fcontainer.id 列是唯一键。
正如我所说,当这两个表连接时,我得到了错误的结果。我原本期望得到与 CTE1 的结果类似的结果,但添加了字段 produkter.produktnamn,但我确实这样做了,但我得到的不是 CTE1 的 2500 个结果,而是大约 1600 行的重复项。
Create Table For Fcontainer and Stämplingar:
CREATE TABLE [dbo].[FContainer] (
[id] NUMERIC (18) IDENTITY (1, 1) NOT NULL,
[PlatsId] NUMERIC (18) CONSTRAINT [DF_FPall_InStoreage] DEFAULT
((0)) NOT NULL,
[Halv] BIT NOT NULL,
[FlaggId] SMALLINT NOT NULL,
[Kragar] SMALLINT NOT NULL,
[TmpFifo] NUMERIC (18) NULL,
[PackTempoTypeNr] SMALLINT NULL,
[Invent] VARCHAR (50) NULL,
CONSTRAINT [PK_FPall] PRIMARY KEY CLUSTERED ([id] ASC) WITH (FILLFACTOR =
90)
);
CREATE TABLE [dbo].[Stämplingar] (
[Stämplingsnr] NUMERIC (18) IDENTITY (1, 1) NOT NULL,
[temponr] NUMERIC (18) NULL,
[Tidpunkt] DATETIME NULL,
[antal] NUMERIC (18) NULL,
[anställd] CHAR (50) NULL,
[Bokad] BIT CONSTRAINT [DF_Stämplingar_Bokad]
DEFAULT ((0)) NOT NULL,
[Skickad] BIT CONSTRAINT [DF_Stämplingar_Skickad]
DEFAULT ((0)) NOT NULL,
[Leveransdatum] DATETIME NULL,
[Papp] NUMERIC (18) NULL,
[daglignr] NUMERIC (18) NULL,
[ID] NUMERIC (18) NULL,
[Anställningsnr] NUMERIC (18) NULL,
CONSTRAINT [PK_Stämplingar] PRIMARY KEY NONCLUSTERED ([Stämplingsnr] ASC)
WITH (FILLFACTOR = 90)
);
从评论的帮助来看,我认为使用左连接似乎是正确的一步。现在我得到了大约 3100 个结果,而不是 1600 个。如果我可以删除重复项,我就可以弄清楚如何为那些无法通过 CTE2 访问的产品获取产品。
有些关系可能有点令人困惑,因为它们没有很好地定义,其中一个表上的 .id 可能与另一个表中的 .id 不同。CTE1 中的查询是我继承并试图扩展的原始查询。
解决方案
正如评论中的讨论所揭示的那样, fcontainer
由于一对多关系,可以与许多产品相关 FContainer
和 Stämplingar
.
试试这个查询,它只会为每个 fcontainer 选择一种产品。
丢失的 fcontainers 是由于 INNER
加入。将其更改为 LEFT
join 将显示所有 fcontainers,甚至是那些与任何产品无关的容器:
;WITH CTE1 AS
(
SELECT
FContainerHylla.Name, FContainerPlats.HyllId,
FContainerPlats.x, FContainerPlats.y,
FContainerPlats.enable, FContainerHylla.Type,
ISNULL( (SELECT MIN(fcontainer.id) AS id
FROM FContainer
WHERE (PlatsId = FContainerPlats.id)
), 0) AS FcId
FROM FContainerPlats
INNER JOIN FContainerHylla ON FContainerPlats.HyllId = FContainerHylla.Id
WHERE (FContainerHylla.Type IN (1, 6, 10))
),
CTE2 AS
(
SELECT
FContainer.id AS SubID, MIN(produkter.Produktnamn) AS Produktnamn
FROM FContainer
INNER JOIN Stämplingar ON FContainer.id = Stämplingar.ID
INNER JOIN Tempo ON Stämplingar.temponr = Tempo.temponr
INNER JOIN Produkter ON Tempo.produktnr = Produkter.Produktnr
GROUP BY
FContainer.id
)
SELECT CTE1.*, CTE2.Produktnamn
FROM CTE1
LEFT JOIN CTE2 ON CTE2.SubID = CTE1.FcId
ORDER BY CTE1.HyllId, CTE1.x, CTE1.y ;
不隶属于 dba.stackexchange