【问题标题】:How to fix SELECT statement to return duplicates如何修复 SELECT 语句以返回重复项
【发布时间】:2021-02-16 19:45:54
【问题描述】:

目前我正在尝试返回一个三表连接以查找我的“曲目”表中的重复曲目标题,并返回曲目编号 |其他连接表的 cd 标题。我的 select 语句目前正在返回连接表中的所有信息,但它不仅仅显示重复项。

我也尝试过使用 group by 和 having 子句来尝试查找 COUNT 的 comptitle。当我尝试它返回一个空表时。

我的表:

CREATE TABLE composition (compid, comptitle,...,
    PRIMARY KEY (compid),...);

CREATE TABLE recording (rcdid,..., compid,
    PRIMARY KEY (rcdid, compid),...);

CREATE TABLE cd (cdid, cdtitle,..., 
    PRIMARY KEY(cdid),...);

CREATE TABLE track (cdid, trknum,..., rcdid, compid,
    PRIMARY KEY (cdid, trknum),...);

我的声明:

SELECT comptitle, trknum, cdtitle
    FROM track JOIN recording ON track.rcdid = recording.rcdid
    JOIN composition ON recording.compid = composition.compid
    JOIN cd ON cd.cdid = track.cdid;

预期输出 |实际:

EXPECTED:
      comptitle      | trknum | cdtitle     
--------------------------------------------
 Cousin Mary         | 2      | Giant Steps 
 Cousin Mary         | 10     | Giant Steps 
 Giant Steps         | 1      | Giant Steps 
 Giant Steps         | 8      | Giant Steps 

ACTUAL:
         comptitle          | trknum |   cdtitle   
----------------------------+--------+-------------
 Giant Steps                | 8      | Giant Steps
 Giant Steps                | 1      | Giant Steps
 Stomp of King Porter       | 1      | Swing
 Sing a Study in Brown      | 2      | Swing
 Cousin Mary                | 14     | Swing
 Cousin Mary                | 10     | Giant Steps

【问题讨论】:

  • 包装成GROUP BY comptitleHAVING COUNT(*)>1
  • @PM77-1 当我这样做时,我会在 trknum 和 cdtitle 中分组。然后当我这样做时,它会给我一张空桌子。

标签: sql postgresql


【解决方案1】:

您需要一个子查询来首先在track 表中找到重复的曲目标题,然后将其连接到其他表中。这个子查询看起来像:

  SELECT rcdid, COUNT(*) AS number
  FROM track
  GROUP BY rcdid
  HAVING COUNT(*) > 1

现在,根据您使用的数据库引擎,您可能可以使用 CTE,使其更具可读性。如果是你的情况,你可以试试:

WITH CTE_DuplicatedTracks AS (
  SELECT rcdid, COUNT(*) AS number
  FROM track
  GROUP BY rcdid
  HAVING COUNT(*) > 1
)
SELECT
  c.comptitle,
  t.trknum,
  cd.cdtitle
FROM
  CTE_DuplicatedTracks dt
  JOIN track t ON
    dt.rcdid = t.rcdid
  JOIN recording r ON
    t.rcdid = r.rcdid
  JOIN composition c ON
    r.compid = c.compid
  JOIN cd
    ON cd.cdid = t.cdid;

如果您的引擎不支持 CTE:

SELECT
  c.comptitle,
  t.trknum,
  cd.cdtitle
FROM
  (
    SELECT rcdid, COUNT(*) as number
    FROM track
    GROUP BY rcdid
    HAVING COUNT(*) > 1
  ) dt
  JOIN track t ON
    dt.rcdid = t.rcdid
  JOIN recording r ON
    t.rcdid = r.rcdid
  JOIN composition c ON
    r.compid = c.compid
  JOIN cd
    ON cd.cdid = t.cdid;

【讨论】:

  • 感谢您的回复。虽然这并没有给我所需的预期输出,但我可以使用它来获得我的答案。但再次感谢您帮助更好地理解 sql。
【解决方案2】:

你可以使用窗口函数:

SELECT comptitle, trknum, cdtitle
FROM (SELECT comptitle, trknum, cdtitle,
             COUNT(*) OVER (PARTITION BY comptitle) as cnt
      FROM track t JOIN
           recording r
           ON t.rcdid = r.rcdid JOIN
           composition c
           ON r.compid = c.compid JOIN
           cd 
           ON cd.cdid = t.cdid
     ) t
WHERE cnt >= 2
ORDER BY cnt, comptitle;

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 2020-04-27
    • 1970-01-01
    • 2019-10-26
    • 1970-01-01
    • 2022-11-30
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多