跳过具有重复列值的行?

发布于 2025-02-10 02:54:14 字数 930 浏览 3 评论 0原文

假设我使用Findall()返回集合,但是许多行在一列中具有相同的值。

-----------------------------
| ID     name    placeId    |
-----------------------------
| 1      abc     123        |
| 2      def     123        | <- skip this (duplicate placeId)
| 3      ghi     456        |
| 4      jkl     789        |
| 5      mno     576        |
| 6      pqr     576        | <- skip this (duplicate placeId)
----------------------------

是否有一种续集的手段来跳过任何具有重复列值的行(第一个除外)?

查询:

const items = await models.Item.findAll({
where: {
    [Op.and]: [
        sequelize.where(distance, { [Op.lte]: radius }),
        sequelize.where(descriptionFilter, { [Op.gte]: 2 }),
        {
            name: {
                [Op.notLike]: `%Example%`
            }
        }, {
            userId: {
                [Op.not]: me.id
            }
        },
    ]
},
order: distance,
limit: 25,
})

Say I'm returning a collection using findAll(), but a number of the rows have identical values in one column.

-----------------------------
| ID     name    placeId    |
-----------------------------
| 1      abc     123        |
| 2      def     123        | <- skip this (duplicate placeId)
| 3      ghi     456        |
| 4      jkl     789        |
| 5      mno     576        |
| 6      pqr     576        | <- skip this (duplicate placeId)
----------------------------

Is there a means in Sequelize to skip any rows (except the first) with duplicate column values?

Query's:

const items = await models.Item.findAll({
where: {
    [Op.and]: [
        sequelize.where(distance, { [Op.lte]: radius }),
        sequelize.where(descriptionFilter, { [Op.gte]: 2 }),
        {
            name: {
                [Op.notLike]: `%Example%`
            }
        }, {
            userId: {
                [Op.not]: me.id
            }
        },
    ]
},
order: distance,
limit: 25,
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

℉服软 2025-02-17 02:54:14

这是一个差距和岛屿问题。使用Raw Postgres查询最容易处理此操作,因此我建议以下内容:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY ID) rn1,
              ROW_NUMBER() OVER (PARTITION BY placeId ORDER BY ID) rn2
    FROM yourTable
),
cte2 AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY placeId, rn1 - rn2
                                 ORDER BY ID) rn
    FROM cte
)

SELECT ID, name, placeId
FROM cte2
WHERE rn = 1
ORDER BY ID;

This is a gaps and islands problem. It would be easiest to handle this using a raw Postgres query, so I suggest the following:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY ID) rn1,
              ROW_NUMBER() OVER (PARTITION BY placeId ORDER BY ID) rn2
    FROM yourTable
),
cte2 AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY placeId, rn1 - rn2
                                 ORDER BY ID) rn
    FROM cte
)

SELECT ID, name, placeId
FROM cte2
WHERE rn = 1
ORDER BY ID;

Demo

以可爱出名 2025-02-17 02:54:14

续集支持聚合功能min(),因此您可以在我们的代码上应用此功能。

const items = await models.Item.findAll({
    attributes: [
        [sequelize.fn('MIN', sequelize.col('ID')), 'ID'],
    ],
    where: {
    [Op.and]: [
        sequelize.where(distance, { [Op.lte]: radius }),
        sequelize.where(descriptionFilter, { [Op.gte]: 2 }),
        {
            name: {
                [Op.notLike]: `%Example%`
            }
        }, {
            userId: {
                [Op.not]: me.id
            }
        },
        group: ['placeId'],
    ]
},
order: distance,
limit: 25,
})

sequelize supports aggregation function min(), so you can apply this on our code.

const items = await models.Item.findAll({
    attributes: [
        [sequelize.fn('MIN', sequelize.col('ID')), 'ID'],
    ],
    where: {
    [Op.and]: [
        sequelize.where(distance, { [Op.lte]: radius }),
        sequelize.where(descriptionFilter, { [Op.gte]: 2 }),
        {
            name: {
                [Op.notLike]: `%Example%`
            }
        }, {
            userId: {
                [Op.not]: me.id
            }
        },
        group: ['placeId'],
    ]
},
order: distance,
limit: 25,
})
心作怪 2025-02-17 02:54:14

PostgreSQL可以做

select distinct on (placeid)
 * from example_table order by placeid,id 

Postgresql can do a job

select distinct on (placeid)
 * from example_table order by placeid,id 

DB Fiddle

樱娆 2025-02-17 02:54:14

也许不是最好的,但它解决了问题:

  SELECT T2.ID, T2.NAME, T2.PLACEID
  FROM
  (
    SELECT T1.*, RANK() OVER(PARTITION BY placeId ORDER BY ID) RNK
    FROM test_tbl T1
  ) T2
  WHERE T2.RNK = 1
  ORDER BY T2.ID

Maybe not the best, but it solves the problem:

  SELECT T2.ID, T2.NAME, T2.PLACEID
  FROM
  (
    SELECT T1.*, RANK() OVER(PARTITION BY placeId ORDER BY ID) RNK
    FROM test_tbl T1
  ) T2
  WHERE T2.RNK = 1
  ORDER BY T2.ID

Fiddle

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文