如何为此编写sql?

时间:2018-03-06 18:20:49

标签: sql node.js postgresql sequelize.js

我这样的桌子

Customer
-ID
-name
-address

Business
-ID
-name
-type

Discount
-ID
-amount
-BusinessID
-position

UsedDiscounts
-CustomerID
-DiscountID

商家有很多折扣。

用户已使用许多折扣,其记录在UsedDiscounts中。

用户只能按位置使用折扣,由位置定义。折扣1,然后折扣2.因此,即使商家有10个折扣,一个客户有资格获得该商家使用折扣的位置+1。

目标:获取用户符合条件的所有折扣。

我的方法是在折扣和已使用的折扣上进行左排除加入。

所以获得所有折扣减去已使用的折扣,然后以某种方式做到最小的位置并获得所有"合格"那些。但是,我可能能够在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

1 个答案:

答案 0 :(得分:0)

您的左连接不会生效,因为您在第二个查询中使用了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";