SQL:选择具有唯一值但所有列的行

时间:2010-02-10 09:09:47

标签: sql

我有2个表:ATTACHEMENTS和EMAILS(类比示例)。 ATTACHEMENTS表保存每个行的ReferenceID到它所属的电子邮件。此外,我的电子邮件可以有0个或更多的附件。

表格如下:

Emails
    UID Column1, Column2 ...up to 20 columns
    1       
    2       
    3       
    4       

Attachements
    UID     ReferenceID //link to EMAILS.UID
    1       2 //this and the one below belong to the same parent.
    2       2
    3       1
    4       3

现在我需要检索带附件的所有电子邮件,无论它们有多少。 我需要获取所有列,所以我想我不能使用distinct,但我只需要具有不同ReferenceID的行。从上表中,我需要得到3的结果。 简而言之:如何选择包含所有列但具有不同referenceID的行? 谢谢

3 个答案:

答案 0 :(得分:1)

不幸的是 DISTINCT 做了什么。因此,要检索不同的ID,您将如何决定从关系中选择哪些“其他”列值?

或者您是否只想检索ID?您可以尝试通过选择平局的第一行/最后一行来检索关系中的详细信息。

为此你可以试试像

这样的东西
DECLARE @Table TABLE(
        UID INT IDENTITY(1, 1),
        ReferenceID INT,
        Col1 VARCHAR(10),
        Col2 VARCHAR(10),
        Col3 VARCHAR(10),
        Col4 VARCHAR(10)
)

INSERT INTO @Table (ReferenceID,Col1, Col2, Col3, Col4) SELECT 2, 1, 1, 1, 1
INSERT INTO @Table (ReferenceID,Col1, Col2, Col3, Col4) SELECT 2, 2, 2, 2, 2
INSERT INTO @Table (ReferenceID,Col1, Col2, Col3, Col4) SELECT 3, 3, 3, 3, 3
INSERT INTO @Table (ReferenceID,Col1, Col2, Col3, Col4) SELECT 4, 4, 4, 4, 4

SELECT  t.*
FROM    @Table t INNER JOIN
        (
            SELECT  ReferenceID,
                    MAX(UID) MUID
            FROM    @Table
            GROUP BY ReferenceID
        ) mID   ON  t.ReferenceID = mID.ReferenceID
                AND t.UID = mID.MUID

答案 1 :(得分:0)

更新:我删除了之前的答案,因为它不再相关

好的,这应该这样做。请注意,我正在使用Microsoft SQL Server表变量来完成这个完整的示例,只需将select语句更改为使用“Emails”& “附件”代替“@Emails”&你桌上的“@Attachements”。

DECLARE @Emails TABLE
(
    [UID] INT,
    [Column1] VARCHAR(20),
    [Column2] VARCHAR(20),
    [Column3] VARCHAR(20),
    [Column4] VARCHAR(20),
    [Column5] VARCHAR(20)
)

DECLARE @Attachements TABLE
(
    [UID] INT,
    [ReferenceID] INT
)

INSERT INTO @Emails ([UID], Column1, Column2, Column3, Column4, Column5) SELECT 1, 'Data 1', 'Data 2', 'Data 3', 'Data 4', 'Data 5'
INSERT INTO @Emails ([UID], Column1, Column2, Column3, Column4, Column5) SELECT 2, 'Data 6', 'Data 7', 'Data 8', 'Data 9', 'Data 10'
INSERT INTO @Emails ([UID], Column1, Column2, Column3, Column4, Column5) SELECT 3, 'Data 11', 'Data 12', 'Data 13', 'Data 14', 'Data 15'
INSERT INTO @Emails ([UID], Column1, Column2, Column3, Column4, Column5) SELECT 4, 'Data 16', 'Data 17', 'Data 18', 'Data 19', 'Data 20'

INSERT INTO @Attachements ([UID], [ReferenceID]) SELECT 1, 2
INSERT INTO @Attachements ([UID], [ReferenceID]) SELECT 2, 2
INSERT INTO @Attachements ([UID], [ReferenceID]) SELECT 3, 1
INSERT INTO @Attachements ([UID], [ReferenceID]) SELECT 4, 3

-- And here's the select!
SELECT e.UID, e.Column1, e.Column2, e.Column3, e.Column4, e.Column5
FROM @Emails e
WHERE EXISTS
    (SELECT 1 FROM @Attachements a WHERE a.ReferenceID = e.UID)

您也可以使用内部JOIN进行DISTINCT,但我更喜欢上面的风格。我不确定哪个更有效率。

SELECT DISTINCT e.UID, e.Column1, e.Column2, e.Column3, e.Column4, e.Column5
FROM @Emails e
    INNER JOIN @Attachements a ON a.ReferenceID = e.UID

P.S。如果表名是英文,那么它是“附件”而不是“附件”。如果是另一种语言,请忽略我! :)

答案 2 :(得分:0)

从电子邮件e,附件a中选择不同的e.uid,col1,col2,...,col20 其中e.uid = a.referenceID

OR

从电子邮件中选择uid,col1,... ,, col20 e.uid in(从附件中选择referenceid)