T-SQL - 两个表/孤立名称的连接

时间:2014-08-13 06:15:55

标签: sql sql-server group-concat sql-server-group-concat

我准备被钉在十字架上,因为我在第一个问题上提出了问题,这是一个可能重复的问题,但我找不到这个问题。

我有三个表,一个产品表,一个链接表和一个带有名称的子表。如果我仍然引起您的注意,请预先加载SQLFiddle >>

CREATE TABLE Product (iProductID int NOT NULL PRIMARY KEY
                    , sProductName varchar(50) NOT NULL
                    , iPartGroupID int NOT NULL)
INSERT INTO Product VALUES
(10001, 'Avionic Tackle', '1'),
(10002, 'Eigenspout', '2'),
(10003, 'Impulse Polycatalyst', '3'),
(10004, 'O-webbing', '2'),
(10005, 'Ultraservo', '3'),
(10006, 'Yttrium Coil', '5')

CREATE TABLE PartGroup (iPartGroupID int NOT NULL
                      , iChildID int NOT NULL)
INSERT INTO PartGroup VALUES
(1, 1),
(2, 2),
(3, 1),
(3, 2),
(3, 3),
(3, 4),
(4, 5),
(4, 6),
(5, 1)

CREATE TABLE PartNames (iChildID int NOT NULL PRIMARY KEY
                      , sPartNameText varchar(50) NOT NULL)
INSERT INTO PartNames VALUES
(1, 'Bulbcap Lube'),
(2, 'Chromium Deltaquartz'),
(3, 'Dilation Gyrosphere'),
(4, 'Fliphose'),
(5, 'G-tightener Bypass'),
(6, 'Heisenberg Shuttle')

我试图找出如何列出所有零件组(可能属于或不属于某个产品),并翻译其子名称。也就是说,如何仅使用链接表和子名称表来列出链接表的所有已翻译元素。我想找到孤儿。

我有两个问题:

SELECT P.iPartGroupID
    ,STUFF(
        (SELECT
            CONCAT(', ', PN.sPartNameText)
            FROM PartGroup PG
            INNER JOIN PartNames PN ON PN.iChildID = PG.iChildID
         WHERE PG.iPartGroupID = P.iPartGroupID
         FOR XML PATH(''), TYPE
        ).value('.', 'VARCHAR(MAX)')
        , 1, 2, ''
        ) AS [Child Elements]
FROM Product P
GROUP BY P.iPartGroupID

这将按名称列出属于产品的所有零件组及其子元素。 iPartGroupID = 4不在这里。

我也有:

SELECT PG.iPartGroupID
    ,STUFF(
        (SELECT
            CONCAT(', ', PGList.iChildID)
            FROM PartGroup PGList
            WHERE PGList.iPartGroupID = PG.iPartGroupID
            FOR XML PATH(''), TYPE
        ).value('.', 'VARCHAR(MAX)')
        , 1, 2, ''
        ) AS [Child Elements]
FROM PartGroup PG
GROUP BY PG.iPartGroupID

按代码列出所有零件组及其子元素。这里介绍了iPartGroupID = 4,但名称未翻译。

我可以使用什么查询列出孤儿部分组(以及孤儿部分):

 4     G-tightener Bypass, Heisenberg Shuttle

理想情况下,它包含在所有其他部分组的列表中,但如果没有,我可以将结果合并。

我查找的每个其他SO问题都使用3个表,或只使用1个表,自己加入别名。有没有人有任何想法?

零件名称中没有XML,对CONCATSELECT '+'没有特别的偏好。

我会链接到其他帖子,但我不能没有分数:(

2 个答案:

答案 0 :(得分:0)

当你使用“翻译”这个词时,我不完全确定你是什么意思。并且您所需的输出似乎与您的示例数据相矛盾(如果我没有丢失某些内容)。

尽管如此,请尝试此查询,也许这就是您所需要的:

select sq.iPartGroupID, cast((
    select pn.sPartNameText + ',' as [data()] from @PartNames pn
        inner join @PartGroup p on pn.iChildID = p.iChildID
    where p.iPartGroupID = sq.iPartGroupID
    order by pn.iChildID
    for xml path('')
    ) as varchar(max)) as [GroupList]
from (select distinct pg.iPartGroupID from @PartGroup pg) sq
    left join @Product pr on sq.iPartGroupID = pr.iPartGroupID
where pr.iProductID is null;

答案 1 :(得分:0)

您可以使用以下方式获得所需的答案

SELECT pg.iPartGroupID,
   CASE COUNT(pg.iPartGroupID)
        WHEN 1 THEN (
                 SELECT pn2.sPartNameText
                 FROM   PartNames pn2
                 WHERE  pn2.iChildID = pg.iPartGroupID
             )
        ELSE (
                 SELECT CASE ROW_NUMBER() OVER(ORDER BY(SELECT 1))
                             WHEN 1 THEN ''
                             ELSE ','
                        END + pn2.sPartNameText
                 FROM   PartNames pn2
                        INNER JOIN PartGroup pg2
                             ON  pg2.iChildID = pn2.iChildID
                 WHERE  pg2.iPartGroupID = pg.iPartGroupID
                        FOR XML PATH('')
             )
   END
FROM   PartGroup pg
GROUP BY
   pg.iPartGroupID