sql - 如何为此编写sql?

标签 sql node.js postgresql sequelize.js

我有这样的 table

Customer
-ID
-name
-address

Business
-ID
-name
-type

Discount
-ID
-amount
-BusinessID
-position

UsedDiscounts
-CustomerID
-DiscountID

商家有很多折扣。

用户使用过多次折扣,记录在 UsedDiscounts 中。

用户只能按订单使用折扣,由职位定义。折扣 1,然后是折扣 2。因此,即使企业有 10 个折扣,一个客户有资格获得该企业使用的折扣的位置 + 1。

目标:获得用户有资格获得的所有折扣。

我的方法是对 Discounts 和 Used Discounts 进行左排除连接。

因此,获得所有折扣减去使用过的折扣,然后以某种方式在位置上做 min 并获得所有“合格”的折扣。但是,我可能能够在 SQL 中实现这一点,但我不知道如何..

示例不完整的 SQL 看起来像这样
SELECT *, min(gd.position)  FROM

(SELECT * FROM "Deals" as d WHERE (d.active = true) AND (d.latitude BETWEEN 40 AND 41) AND (d.longitude BETWEEN -75 AND -70)) AS gd

LEFT JOIN

(SELECT du."DealId" FROM "DealsUsed" AS du WHERE du."CustomerId" = 1) AS bd

ON gd.id = bd."DealId"
WHERE bd."DealId" IS NULL
GROUP BY gd."UserId";

给出错误的输出
Sample data:

Customer
--------
id   name  address
0    Tobby   93903903
1    Emi     3839039
2    Loop    393030

Business
--------
id   name   type
0    Cool   flower
1    Corner car
2    New    deli
3    Side   printing
4    Big    car

Discount
--------
id  amount  businessId  position
0   10       0              0
1   22       3              1
2   10       3              2
3   43       2              0
4   23       5              0
5   10       5              1

Used Discount
----------
customerId    discountId
1              2


outcome for customer 1 , emi, shouuld be 
Discounts
--------
id  amount  businessId  position
0   10       0              0
4   23       5              0
3   43       2              0
5   10       5              1

最佳答案

您的左连接不会生效,因为您在第二个查询中使用了 where 子句:

删除 where 子句:

SELECT *, min(gd.position)  FROM

(SELECT * FROM "Deals" as d WHERE (d.active = true) AND (d.latitude BETWEEN 40 AND 41) AND (d.longitude BETWEEN -75 AND -70)) AS gd

LEFT JOIN

(SELECT du."DealId" FROM "DealsUsed" AS du) AS bd

ON gd.id = bd."DealId"
WHERE bd."DealId" IS NULL
GROUP BY gd."UserId";

不建议将 Group bySelect * 一起使用。只需选择您需要的字段。就像是:
SELECT gd."UserId", min(gd.position)  FROM

(SELECT * FROM "Deals" as d WHERE (d.active = true) AND (d.latitude BETWEEN 40 AND 41) AND (d.longitude BETWEEN -75 AND -70)) AS gd

LEFT JOIN

(SELECT du."DealId" FROM "DealsUsed" AS du) AS bd

ON gd.id = bd."DealId"
WHERE bd."DealId" IS NULL
GROUP BY gd."UserId";

您可以在像之后使用 where 子句:
SELECT gd."UserId",bd."CustomerId", min(gd.position)  FROM

(SELECT * FROM "Deals" as d WHERE (d.active = true) AND (d.latitude BETWEEN 40 AND 41) AND (d.longitude BETWEEN -75 AND -70)) AS gd

LEFT JOIN

(SELECT du."DealId" FROM "DealsUsed" AS du) AS bd

ON gd.id = bd."DealId"
WHERE bd."DealId" IS NULL and bd."CustomerId" = 1
GROUP BY gd."UserId";

关于sql - 如何为此编写sql?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49137542/

相关文章:

Postgresql SQL GROUP BY 时间间隔任意精度(低至毫秒)

sql - 如何查询关联不存在或全部具有非空值的记录?

mysql - 案例 MySQL - 选择作为值

node.js - 如何使用 Node 将 ReactJS 组件渲染为 HTML 字符串?

javascript - Express-Session 不适用于 Express 4.13 吗?

javascript - 使用正则表达式比较mongodb中的车辆编号

sql - t-sql表列到字符串

c# - 如何在sql数据库后端插入2个值的总和

MySQL 返回当月所有日期的计数,包括结果为零的日期

postgresql - 如何在 Postgresql/Postgis 中创建新的 SRID?