从 table A 中获取所有记录,其中 id = B 中的 somvalue 加上 B 中没有 id 的记录

Fetch all records from table A where id = somvalue in B plus records which don't have id in B

我有两个 table 一个 coupons table 和一个 coupon_city_map table.

id coupon_code
1 OFFER20
2 OFFER10
3 OFFER50
4 OFFER40
5 OFFER90
coupon_Id city_id
1 2
2 3
3 4
4 2

我需要 city_id = 2.

的 ID 为 1 4, and 5 的优惠券

所以它应该获取所有 city_id=2 的优惠券,即 ID 为 1 and 4

的优惠券

它还应该获取 coupon_city_map 中没有密钥的优惠券,即 5.

这是我试过的方法,但是 [Op.or] 中的查询不起作用,而是 returns 所有的优惠券。

let coupons = await Coupon.findAll({
      where: {
        [Op.or]: [
          { '$CouponCities.city_id$': city_id },
          { '$CouponCities.coupon_id$': null },
        ],
        ...filters // other filter like is_active: true
      },
      include: {
        model: CouponCity,
        attributes: [],
      },
      attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount', 'discount_upto', 'description', 'display'],
    });

正在生成查询

SELECT `Coupon`.`id`, 
       `Coupon`.`coupon_code`, 
       `Coupon`.`discount_per`, 
       `Coupon`.`flat_discount`, 
       `Coupon`.`discount_upto`, 
       `Coupon`.`description`, 
       `Coupon`.`display` 
FROM `coupons` AS `Coupon` 
LEFT OUTER JOIN `coupon_city_map` AS `CouponCities` ON `Coupon`.`id` = `CouponCities`.`coupon_id` 
WHERE (`Coupon`.`user_id` IS NULL OR `Coupon`.`user_id` = 1) 
  AND `Coupon`.`is_active` = true 
  AND `Coupon`.`is_external` = false 
  AND `Coupon`.`start_date` < '2020-12-30 10:33:20' 
  AND `Coupon`.`expiry_date` > '2020-12-30 10:33:20';

更新 我也在下面试过,但它仍然退回所有优惠券。

let coupons = await Coupon.findAll({
    // where: {
    //   ...filters,
    // },
    include: {
      model: CouponCity,
      required: false,
      where: {
        [Op.or]: [
          {
            zone_id: zoneId,
          }, {
            coupon_id: null,
          },
        ],
      },
      attributes: [],
    },
    attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount','discount_upto', 'description', 'display'],
 });

...并生成以下查询。

SELECT `Coupon`.`id`, 
       `Coupon`.`coupon_code`, 
       `Coupon`.`discount_per`, 
       `Coupon`.`flat_discount`, 
       `Coupon`.`discount_upto`, 
       `Coupon`.`description`, 
       `Coupon`.`display` 
FROM   `coupons` AS `Coupon` 
       LEFT OUTER JOIN `coupon_city_map` AS `CouponCities` 
                    ON `Coupon`.`id` = `CouponCities`.`coupon_id` 
                       AND ( `CouponCities`.`zone_id` = 1 
                             AND `CouponCities`.`coupon_id` IS NULL ) 
WHERE  `Coupon`.`is_active` = true 
       AND `Coupon`.`is_external` = false; 

使用 UNION

您可以像下面这样写查询

SELECT coupons.* 
FROM   coupons, 
       coupon_city_map 
WHERE  coupons.id = coupon_city_map.coupon_id 
       AND coupon_city_map.city_id = 2 
UNION 
SELECT coupons.* 
FROM   coupons 
WHERE  coupons.id NOT IN(SELECT coupon_city_map.coupon_id 
                         FROM   coupon_city_map)

这对我有用,查询很乱,但它有效。我发布了所有代码,以便感兴趣的人更好地理解。

这里zone是城市。

{
  const filters = {
    start_date: {
      [Op.lt]: new Date(),
    },
    expiry_date: {
      [Op.gt]: new Date(),
    },
  };
  if (userId) {
    filters[Op.or] = [{
      user_id: null,
    }, {
      user_id: userId,
    }];
    filters[Op.and] = {
      [Op.or]: [
        sequelize.literal('CouponZones.zone_id = 1'),
        sequelize.literal('CouponZones.coupon_id IS  null')
      ],
    };
  } else {
    filters.user_id = null;
  }
  let coupons = await Coupon.findAll({
    where: {
      ...filters,
    },
    include: {
      model: CouponZone,
      attributes: [],
    },
    attributes: ['id', 'coupon_code', 'discount_per', 'flat_discount', 'discount_upto', 'description', 'display'],
  });

这是它生成的查询。

SELECT `Coupon`.`id`, 
       `Coupon`.`coupon_code`, 
       `Coupon`.`discount_per`, 
       `Coupon`.`flat_discount`, 
       `Coupon`.`discount_upto`, 
       `Coupon`.`description`, 
       `Coupon`.`display` 
FROM   `coupons` AS `Coupon` 
       LEFT OUTER JOIN `coupon_zone_map` AS `CouponZones` 
                    ON `Coupon`.`id` = `CouponZones`.`coupon_id` 
WHERE  ( `Coupon`.`user_id` IS NULL 
          OR `Coupon`.`user_id` = 1 ) 
       AND ((CouponZones.zone_id = 1 OR CouponZones.coupon_id IS  null)) 
       AND `Coupon`.`is_active` = true 
       AND `Coupon`.`is_external` = false;