SQL Server DISTINCT和GROUP BY仍返回重复项(子查询格式)

时间:2017-08-08 19:59:47

标签: sql-server database postgresql

感谢社区,我能解决一个问题,但又创建了另一个问题。当我运行此查询时,它返回重复项:

SELECT 
    a.*
    , b.Bytes
FROM
    (
SELECT DISTINCT
    a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid
FROM
    "AM-Martin".dbo.CpCore_Site a_inner
    INNER JOIN "AM-Martin".dbo.CpSm_Face b_inner on b_inner.SiteId = a_inner.Oid
WHERE
    b_inner.RetiredOn LIKE '%9999%'
     AND b_inner.Number LIKE N'%LA%' OR b_inner.Number LIKE N'%LC%' OR b_inner.Number LIKE N'%BH%'
     AND b_inner.Latitude > 0.0
) AS a
INNER JOIN "AM-Martin_bin".dbo.CpCore_Image b on a.Oid = b.OwnerId;

所以我尝试更改它并使用GROUP BY运行此查询以查看我是否可以删除重复项但它不起作用我仍然得到重复项:

SELECT 
    a.*
    , b.Bytes
FROM
    (
SELECT 
    a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid
FROM
    "AM-Martin".dbo.CpCore_Site a_inner
    INNER JOIN "AM-Martin".dbo.CpSm_Face b_inner on b_inner.SiteId = a_inner.Oid
WHERE
    b_inner.RetiredOn LIKE '%9999%'
     AND b_inner.Number LIKE N'%LA%' OR b_inner.Number LIKE N'%LC%' OR b_inner.Number LIKE N'%BH%'
     AND b_inner.Latitude > 0.0

     GROUP BY 
      a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid


) AS a
INNER JOIN "AM-Martin_bin".dbo.CpCore_Image b on a.Oid = b.OwnerId;

在你问之前我确实需要包括图像在内的每一栏。任何帮助将不胜感激。我的目标是删除所有重复项。

以下是我的结果中的两个示例,它们是第93行和第94行的重复:

duplicate photo

我以前在没有子查询的情况下运行了查询但遇到了图片列的其他问题,请参阅Split SQL query into a nested query (subquery)

更新

我运行了以下查询并仍然收到了重复项:

SELECT DISTINCT
    a.*
    , cast(cast(b.Bytes as varbinary(max)) as varchar(max)) as Bytes
FROM
    (
SELECT 
    a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid
FROM
    "AM-Martin".dbo.CpCore_Site a_inner
    INNER JOIN "AM-Martin".dbo.CpSm_Face b_inner on b_inner.SiteId = a_inner.Oid
WHERE
    b_inner.RetiredOn LIKE '%9999%'
     AND b_inner.Number LIKE N'%LA%' OR b_inner.Number LIKE N'%LC%' OR b_inner.Number LIKE N'%BH%'
     AND b_inner.Latitude > 0.0
) AS a
INNER JOIN "AM-Martin_bin".dbo.CpCore_Image b on a.Oid = b.OwnerId;

我得到以下结果:

enter image description here

如果我运行此查询,我会得到我想要的结果:

SELECT 
    "AM-Martin".dbo.CpCore_Site.Number,"AM-Martin".dbo.CpCore_Site.Latitude,"AM-Martin".dbo.CpCore_Site.Longitude,"AM-Martin".dbo.CpSm_Face.RetiredOn,CAST("AM-Martin_bin".dbo.CpCore_Image.Bytes as Varbinary), "AM-Martin".dbo.CpCore_Site.Name, "AM-Martin".dbo.CpCore_Site.Zipcode
FROM
    "AM-Martin".dbo.CpCore_Site

INNER JOIN "AM-Martin".dbo.CpSm_Face on "AM-Martin".dbo.CpSm_Face.SiteId = "AM-Martin".dbo.CpCore_Site.Oid
INNER JOIN "AM-Martin_bin".dbo.CpCore_Image on "AM-Martin".dbo.CpSm_Face.Oid = "AM-Martin_bin".dbo.CpCore_Image.OwnerId

WHERE
    "AM-Martin".dbo.CpSm_Face.RetiredOn LIKE '%9999%'

     AND "AM-Martin".dbo.CpCore_Site.Number LIKE N'%LA%' OR "AM-Martin".dbo.CpCore_Site.Number LIKE N'%LC%' OR "AM-Martin".dbo.CpCore_Site.Number LIKE N'%BH%'


     AND "AM-Martin".dbo.CpCore_Site.Latitude > 0.0

GROUP BY "AM-Martin".dbo.CpCore_Site.Number,"AM-Martin".dbo.CpCore_Site.Latitude,"AM-Martin".dbo.CpCore_Site.Longitude,"AM-Martin".dbo.CpSm_Face.RetiredOn,CAST("AM-Martin_bin".dbo.CpCore_Image.Bytes as Varbinary), "AM-Martin".dbo.CpCore_Site.Name, "AM-Martin".dbo.CpCore_Site.Zipcode;

但是这个问题现在变成了我将sql结果转换为postgres时我无法再渲染图像这就是为什么我试图保持图像数据的原因而不转换为varbinary并将它们转移到postgres。

更新2

我运行了高分辨率的查询,我注意到他们所属的每个所有者ID都有多个图像。我需要调整查询,只显示每个所有者ID一个,而不是每个所有者ID显示一个。

enter image description here

3 个答案:

答案 0 :(得分:4)

没有样本数据很难说,但我最初的想法是你的子查询返回唯一值,因为distinct只适用于子查询。但是在加入第二个表时会有多个匹配(" AM-Martin_bin" .dbo.CpCore_Image)。

同样适用于"组",它仅适用于子查询,在加入第二个表时有机会重复返回。

希望这有帮助。

答案 1 :(得分:2)

为了获得不同的图像数据类型值,您需要将图像数据类型字段转换为varchar(max)

  

e.g。 cast(cast(b.Bytes as varbinary(max))as varchar(max))as Bytes

请尝试关注更新的查询。看看是否有帮助

SELECT DISTINCT
    a.*
    , cast(cast(b.Bytes as varbinary(max)) as varchar(max)) as Bytes
FROM
    (
SELECT 
    a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid
FROM
    "AM-Martin".dbo.CpCore_Site a_inner
    INNER JOIN "AM-Martin".dbo.CpSm_Face b_inner on b_inner.SiteId = a_inner.Oid
WHERE
    b_inner.RetiredOn LIKE '%9999%'
     AND b_inner.Number LIKE N'%LA%' OR b_inner.Number LIKE N'%LC%' OR b_inner.Number LIKE N'%BH%'
     AND b_inner.Latitude > 0.0
) AS a
INNER JOIN "AM-Martin_bin".dbo.CpCore_Image b on a.Oid = b.OwnerId;

答案 2 :(得分:1)

如果您每个网站只需要1张图片而且哪张图片不重要,则可以使用交叉应用代替内部连接

SELECT 
    a.*
    , b.Bytes
FROM
    (
SELECT DISTINCT
    a_inner.Number
    , a_inner.Latitude
    , a_inner.Longitude
    , b_inner.RetiredOn
    , a_inner.Name
    , a_inner.Zipcode
    , b_inner.Oid
FROM
    "AM-Martin".dbo.CpCore_Site a_inner
    INNER JOIN "AM-Martin".dbo.CpSm_Face b_inner on b_inner.SiteId = a_inner.Oid
WHERE
    b_inner.RetiredOn LIKE '%9999%'
     AND b_inner.Number LIKE N'%LA%' OR b_inner.Number LIKE N'%LC%' OR b_inner.Number LIKE N'%BH%'
     AND b_inner.Latitude > 0.0
) AS a
CROSS APPLY(SELECT TOP 1 
                Bytes 
            FROM "AM-Martin_bin".dbo.CpCore_Image b 
            WHERE a.Oid = b.OwnerId) b;

您可以通过添加"命令来更改您为具有多个图像的网站选择的图像。在交叉应用子查询中,以便您想要的图像是第一个,或者添加一个额外的过滤器。