简体   繁体   English

未购买的 MySQL 查询客户

[英]MySQL Query Customers Who Have Not Bought

Background:背景:

We are setting up a promotions system to give away free products to registered customers.我们正在建立一个促销系统,向注册客户赠送免费产品。 We're trying to design a database which is flexible enough to handle multiple products, and giveaways.我们正在尝试设计一个足够灵活的数据库来处理多种产品和赠品。 The requirements are that products may be given away on a drip basis on a first come basis to qualified customers.要求是产品可以按先到先到的方式分发给合格的客户。

Example:例子:

Apple wants to give away 1000 ipads in March.苹果希望在 3 月份赠送 1000 台 ipad。

They want to give away maximum of 1 per hour.他们希望每小时最多赠送 1 个。

They want to give it to customers who are in California or New York.他们想把它提供给在加利福尼亚或纽约的客户。

They want to limit how many free ipads a customer can get (limit 1 per 15 days).他们想限制客户可以获得的免费 ipad 数量(每 15 天限制 1 个)。

Data Structure:数据结构:

  • Products - 1 entry per unique product.产品- 每个独特产品 1 个条目。 eg Apple iPad例如苹果 iPad

  • ProductGiveAways产品赠品

    • ProductID: AppleIpad产品编号:AppleIpad
    • Quantity:1000数量:1000
    • StartDate: 03/01/2014开始日期:03/01/2014
    • End Date 03/31/2014结束日期 03/31/2014
    • CustomerState: California,NewYork客户状态:加利福尼亚州,纽约州
    • PurchaseLimitDays: 15购买限制天数:15

Problem:问题:

With the above structure we are able to do a query against our customers table and find out which are qualified for the promotion.通过上述结构,我们可以对客户表进行查询,并找出哪些符合促销条件。

What I cannot figure out is the best way to:我无法弄清楚的是最好的方法是:

  1. Query customers in California or New York (is this a good use case for a join and another table?)查询加利福尼亚或纽约的客户(这是一个连接和另一个表的好用例吗?)
  2. When a customer logs in to see what free items are not available to him, how can I exclude the Apple iPad if the customer has already gotten this freebie?当客户登录查看哪些免费商品不提供给他时,如果客户已经获得此免费赠品,我如何排除 Apple iPad?

In other words:换句话说:

  • Say amazon.com wants to show me DVDs which I have not already bought.假设 amazon.com 想要向我展示我尚未购买的 DVD。 What is the proper way to query that?查询的正确方法是什么?

  • Is the right approach to first get a list of previously bought products and then Query with a NOT clause?首先获取以前购买的产品列表,然后使用 NOT 子句进行查询是正确的方法吗?

I'm assuming you'll have a table for what has been given away.我假设你会有一张桌子来存放已经赠送的东西。 In this table I would include a column for recipient id which can map back to the customer table.在此表中,我将包含一个收件人 ID 列,该列可以映射回客户表。 You can then create queries to find eligible recipients by searching for customers who have not met disqualifying conditions.然后,您可以通过搜索不符合取消资格条件的客户来创建查询以查找符合条件的收件人。

select customerid 
from customer
where customerid not in (
                          select recipientid
                          from givenaway
                          where ..... and ....
                         )

Because there's not a definitive data structure defined, I'm going to use the following which you can tailor to whatever data structure you have designed yourself:因为没有定义明确的数据结构,我将使用以下内容,您可以根据自己设计的任何数据结构进行定制:

  • Product产品
    • ProductId - INTEGER ( IDENTITY and PRIMARY KEY ) ProductId - INTEGERIDENTITYPRIMARY KEY
    • ProductName - VARCHAR产品名称 - VARCHAR
  • States状态
    • StateId - INTEGER ( IDENTITY and PRIMARY KEY ) StateId - INTEGERIDENTITYPRIMARY KEY
    • StateName - VARCHAR状态名称 - VARCHAR
  • Customer顾客
    • CustomerId - INTEGER ( IDENTITY and PRIMARY KEY ) CustomerId - INTEGER ( IDENTITYPRIMARY KEY )
    • StateId - INTEGER ( FOREIGN KEY ) StateId - INTEGER (外FOREIGN KEY
  • Promotion晋升
    • PromotionId - INTEGER ( IDENTITY and PRIMARY KEY ) PromotionId - INTEGERIDENTITYPRIMARY KEY
    • ProductId - INTEGER ( FOREIGN KEY ) ProductId - INTEGER (外FOREIGN KEY
    • Quantity - INTEGER数量 - INTEGER
    • StartDate - DATETIME开始日期 - 日期DATETIME
    • End Date - DATETIME结束日期 - 日期DATETIME
    • PurchaseLimitDays - INTEGER PurchaseLimitDays - INTEGER
  • PromotionState促销状态
    • PromotionId - INTEGER ( FOREIGN KEY )促销INTEGER - INTEGER (外FOREIGN KEY
    • StateId - INTEGER ( FOREIGN KEY ) StateId - INTEGER (外FOREIGN KEY

So in answer to your questions:所以回答你的问题:

Query customers in California or New York (is this a good use case for a join and another table?)查询加利福尼亚或纽约的客户(这是一个连接和另一个表的好用例吗?)

Personally I would join to a centralized state table ( PromotionState ) in my above example, I'm sure there's a better way but you could do a condition such as:就我个人而言,我会在上面的示例中加入集中状态表 ( PromotionState ),我确定有更好的方法,但您可以执行以下条件:

WHERE  
    (SELECT COUNT * FROM PromotionState x WHERE x.PromotionId = p.PromotionId) = 0
    OR NOT(ps.PromotionId IS NULL)

Alternatively you could do a GROUP BY and HAVING , using all the other columns as the items to GROUP BY and something like HAVING COUNT * = 0 OR HAVING SUM CASE WHEN (Conditions met) THEN 1 ELSE 0 END = 0或者,您可以执行GROUP BYHAVING ,使用所有其他列作为GROUP BY的项目,以及类似HAVING COUNT * = 0HAVING SUM CASE WHEN (Conditions met) THEN 1 ELSE 0 END = 0

When a customer logs in to see what free items are not available to him, how can I exclude the Apple iPad if the customer has already gotten this freebie?当客户登录查看哪些免费商品不提供给他时,如果客户已经获得此免费赠品,我如何排除 Apple iPad?

Say amazon.com wants to show me DVDs which I have not already bought.假设 amazon.com 想要向我展示我尚未购买的 DVD。 What is the proper way to query that?查询的正确方法是什么?

As I've said you could use GROUP BY and HAVING to determine whether an item has been previously "won" by either using COUNT or SUM正如我所说,您可以使用GROUP BYHAVING来确定以前是否通过使用COUNTSUM来“赢得”某个项目

Is the right approach to first get a list of previously bought products and then Query with a NOT clause?首先获取以前购买的产品列表,然后使用 NOT 子句进行查询是正确的方法吗?

There are probably better ways, sub queries can get very heavy and sluggish, I'd recommend trying some of the above techniques and then using a profiler to hopefully make it more efficient.可能有更好的方法,子查询可能会变得非常繁重和缓慢,我建议您尝试上述一些技术,然后使用分析器来提高效率。

Some database design一些数据库设计

First, when you set the CustomerState to California,NewYork you are violating the First Normal Form of database design.首先,当您将CustomerState设置为California,NewYork您违反了数据库设计的First Normal Form

So let's reorganize your domain model.因此,让我们重新组织您的域模型。

State - 1 Entry per unique state ...状态- 每个独特状态 1 个条目......

Customer - 1 Entry per unique customer StateId: (California|NewYork|...) ...客户- 每个唯一客户 StateId 1 个条目:(加利福尼亚|纽约|...)...

Product - 1 Entry per unique product ...产品- 每个独特产品 1 个条目...

ProductGiveAways - Many entries per product ProductID Quantity StartDate End Date PurchaseLimitDays ... ProductGiveAways - 每个产品的多个条目 ProductID Quantity StartDate End Date PurchaseLimitDays ...

ProductGiveAways_State ProductGiveAwaysId StateId ... ProductGiveAways_State ProductGiveAwaysId STATEID ...

Customer_Product - 1 Entry per bought product by customer CustomerId ProductId PurchaseDate ... Customer_Product - 每个客户购买的产品有 1 个条目 CustomerId ProductId PurchaseDate ...

Technical issues技术问题

When you want to query custoners in California or New York, all you have to do now is :当您想查询加利福尼亚或纽约的客户时,您现在要做的就是:

// This is just an example, you have to change the 'California', 'New York' with their ids
SELECT * FROM Customer WHERE StateId IN ('California', 'New York')

When a customer logs in to see what free items are available to him :当客户登录以查看他可以使用哪些免费商品时:

// It's not an accurate sql, just an example
SELECT Product.* 
FROM Product 
JOIN ProductGiveAways ON ProductId
JOIN ProductGiveAways_State ON ProductGiveAwaysId
WHERE ProductId NOT IN (
    SELECT ProductId FROM Customer_Product JOIN ProductGiveAways ON ProductId
    WHERE CustomerId = /* the customer id */
    AND ( TO_DAYS(now()) - TO_DAYS(PurchaseDate) ) < PurchaseLimitDays
) 
AND StateId = /* customer StateId */
AND StartDate < now() < End Date // Elligible ProductGiveAways

For Laravel We Use Something Like this, i hope you can relate to this query or you can use online laravel query converter for using it in mysql ( orator )对于 Laravel 我们使用类似这样的东西,我希望您可以与此查询相关联,或者您可以使用在线 Laravel 查询转换器在 mysql ( orator ) 中使用它

$user_id = auth()->user()->id;

Product::where('status', 'active')
->whereNotIn('id', function($query) use ($user_id) {
$query->select('product_id')->from(new OrderProduct->getTable())
->where('user_id', $user_id)->where('status', 'delivered');
}); });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MYSQLQuery-如何创建查询,我们必须列出由同一位歌手购买了特定数量专辑的客户 - MYSQLQuery- How to create a query where we have to list out customers who have bought a specific number of album by the same singer 购买此产品的顾客也购买了此产品......帮助 - Customers who bought this also bought this… Help MySQL查询以查找已下订单0 /未下订单的客户 - MySQL query to find customers who have made 0 orders / no orders MySQL查询查找订单最多的客户 - MySQL query to find customers who have made the most orders MySQL Query查找订购了两种特定产品的客户 - MySQL Query to find customers who have ordered two specific products 列出已购买同一对MySQL产品的客户 - List customers that have bought the same pair of products MySQL 查询客户与所列产品一起购买的产品 - query for what customers have bought together with the listed product 仅在本月而非sql之前购买的客户 - Customers who bought only this month and not before sql 是否有查询选择哪些客户购买了特定产品以及这些客户购买了哪些其他产品? - Is there a query which select which customers have bought a specific product and what other products did these same customers buy? MySQL查询不会返回所需的结果。 没有订单的客户不显示 - MySQL query does not return needed result. Customers who does not have any orders, does not show
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM