跨关系的可选查询

时间:2018-02-13 16:14:41

标签: node.js postgresql sequelize.js

我有两个表来处理我的应用程序中的优惠券代码。

第一个(coupon)存储优惠券代码及其提供的折扣:

| id | code       | public | discount_percent |
|----|------------|--------|------------------|
| 1  | EXAMPLE    | true   | 10               |
| 2  | PRIV_12981 | false  | 30               |

公开表示任何人都可以声明优惠券代码。

第二个(user_coupon)表存储有权兑换私人优惠券的用户,以及他们的优惠券实例是否已兑现:

| id | coupon_id | user_id | redeemed |
|----|-----------|---------|----------|
| 1  | 2         | 1       | false    |

我需要进行以下查询(伪代码):

SELECT * from coupons
    WHERE (
        code = 'PRIV_12981'
        AND (
            public = true
            OR (
                user_coupon.user_id = 1
                AND user_coupon.redeemed = false
            )
        )
   )

此查询应检查所提供的代码是否存在优惠券是公共的,还是在user_coupon表中为所提供的user_id提供了相应的条目且尚未兑换。

我正在使用Sequelize,并编写了以下查询:

Coupon.findOne({
  where: {
    [Sequelize.Op.and]: [
      {
        code: 'TEST'
      },
      {
        [Sequelize.Op.or]: [
          {
            public: true
          },
          {
            [Sequelize.Op.and]: [
              Sequelize.where(
                Sequelize.col('user_coupons.redeemed'), false
              ),
              Sequelize.where(
                Sequelize.col('user_coupons.user_id'), 1
              )
            ]
          }
        ]
      }
    ]
  },
  include: [{
    model: UserCoupon,
    as: 'user_coupons',
  }]
}).then(coupon => {
  console.log(coupon)
})

这将生成以下SQL:

SELECT "Coupon".*,
       "user_coupons"."id" AS "user_coupons.id",
       "user_coupons"."coupon_id" AS "user_coupons.coupon_id",
       "user_coupons"."user_id" AS "user_coupons.user_id",
       "user_coupons"."redeemed" AS "user_coupons.redeemed",
       "user_coupons"."created_at" AS "user_coupons.created_at",
       "user_coupons"."updated_at" AS "user_coupons.updated_at"
FROM
  (SELECT "Coupon"."id",
          "Coupon"."code",
          "Coupon"."public",
          "Coupon"."discount_percent",
          "Coupon"."max_discount",
          "Coupon"."valid_from",
          "Coupon"."invalid_after",
          "Coupon"."created_at",
          "Coupon"."updated_at"
   FROM "public"."coupon" AS "Coupon"
   WHERE ("Coupon"."code" = 'TEST'
          AND ("Coupon"."public" = TRUE
               OR ("user_coupons"."redeemed" = FALSE
                   AND "user_coupons"."user_id" = 1)))
   LIMIT 1) AS "Coupon"
LEFT OUTER JOIN "public"."user_coupon" AS "user_coupons" ON "Coupon"."id" = "user_coupons"."coupon_id";

但是,它会引发以下错误:

  

缺少表格#34; user_coupons"

的FROM子句条目

Sequelize查询我做错了什么?

1 个答案:

答案 0 :(得分:0)

我发现错误实际上并不在我的查询结构中,这是由于我使用了findOne,这会在查询中添加LIMIT 1,从而导致错误。通过Coupon.findAll查询修复此问题,