繁体   English   中英

从SQL查询中删除重复项(不仅仅是“使用不同”)

[英]Removing duplicates from a SQL query (not just “use distinct”)

这可能很简单,这是我的查询:

SELECT DISTINCT U.NAME, P.PIC_ID
FROM USERS U, PICTURES P, POSTINGS P1
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND P.CAPTION LIKE '%car%';

但是这只会删除一行具有相同的u.name和p.pic_id的重复项。 我想要它,如果有任何重复的名称,它只是遗漏了其他行。 这是一个奇怪的查询,但一般来说,如何将distinct应用于SELECT子句的单个列?

任意选择保持最小PIC_ID。 另外,请避免使用隐式连接语法。

SELECT U.NAME, MIN(P.PIC_ID)
    FROM USERS U
        INNER JOIN POSTINGS P1
            ON U.EMAIL_ID = P1.EMAIL_ID
        INNER JOIN PICTURES P
            ON P1.PIC_ID = P.PIC_ID
    WHERE P.CAPTION LIKE '%car%'
    GROUP BY U.NAME;

你的问题有点令人困惑; 你想每个用户只显示一行,或者你想在每张图片中显示一行但是在U.NAME字段中抑制重复值? 我想你想要第二个; 如果不是第一个有很多答案。

是否显示重复值是显示逻辑,SQL实际上并不是这样设计的。 您可以在循环中使用游标来逐行处理结果,但是会丢失很多性能。 如果你有一个像.NET语言或Java这样的“智能”前端语言,那么无论你将这些数据放入何种结构中,都可以通过廉价的方式操作来抑制重复值,最后在UI中显示它。

如果您正在使用Microsoft SQL Server,并且要在数据层完成转换HAS,您可以考虑使用CTE(计算表表达式)来保存初始查询,然后根据是否从CTE的每一行中选择值上一行中的列包含相同的数据。 它会比光标更高效,但无论如何它都会有点混乱。 注意:

USING CTE (Row, Name, PicID)
AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY U.NAME, P.PIC_ID),
       U.NAME, P.PIC_ID
    FROM USERS U
        INNER JOIN POSTINGS P1
            ON U.EMAIL_ID = P1.EMAIL_ID
        INNER JOIN PICTURES P
            ON P1.PIC_ID = P.PIC_ID
    WHERE P.CAPTION LIKE '%car%'
    ORDER BY U.NAME, P.PIC_ID 
)
SELECT
    CASE WHEN current.Name == previous.Name THEN '' ELSE current.Name END,
    current.PicID
FROM CTE current
LEFT OUTER JOIN CTE previous
   ON current.Row = previous.Row + 1
ORDER BY current.Row

以上示例是TSQL特定的; 它不能保证在PL / SQL等任何其他DBPL中工作,但我认为大多数企业级SQL引擎都有类似的东西。

您需要告诉查询要为其他列选择哪个值, MINMAX看起来是合适的选择。

 SELECT
   U.NAME, MIN(P.PIC_ID)
 FROM
   USERS U,
   PICTURES P,
   POSTINGS P1
 WHERE
   U.EMAIL_ID = P1.EMAIL_ID AND
   P1.PIC_ID = P.PIC_ID AND
   P.CAPTION LIKE '%car%'
 GROUP BY
   U.NAME;

如果我理解正确,您希望列出仅在一列上排除重复,内部联接到子选择

select u.* [whatever joined values]
from users u
inner join
(select name from users group by name having count(*)=1) uniquenames
on uniquenames.name = u.name

如果我理解正确,您需要一个具有相同名称(及其不同ID)的所有图片的列表,以使其名称在表格中出现多次。 我认为这样可以解决问题:

SELECT U.NAME, P.PIC_ID
FROM USERS U, PICTURES P, POSTINGS P1
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND U.Name IN (
SELECT U.Name 
FROM USERS U, PICTURES P, POSTINGS P1
WHERE U.EMAIL_ID = P1.EMAIL_ID AND P1.PIC_ID = P.PIC_ID AND P.CAPTION LIKE '%car%';
GROUP BY U.Name HAVING COUNT(U.Name) > 1)

我没有执行它,因此可能存在语法错误或两个语法错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM