分类 mysql 下的文章

假设我们有一个商品是T恤衫,它有两种规格类型:颜色和尺寸。每种类型的规格都有多个可能的值,并且每个组合都有不同的价格和库存量。

示例数据
商品表 (Product)
product_id name description category_id brand_id
1 T恤衫 舒适透气的纯棉T恤 3 2
规格类型表 (Specification_Type)
spec_type_id name unit
1 颜色 -
2 尺寸 -
规格值表 (Specification_Value)
spec_value_id spec_type_id value
1 1 红色
2 1 蓝色
3 2 S
4 2 M
5 2 L
商品规格表 (Product_Specification)
这里记录了哪些规格类型适用于该商品。

id product_id spec_value_id
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
SKU表 (Stock_Keeping_Unit)
每个SKU代表一种特定的颜色和尺寸组合。

sku_id product_id price stock_quantity barcode
1 1 99.00 100 12345678
2 1 99.00 150 12345679
3 1 109.00 200 12345680
SKU与规格关系表 (SKU_Specification_Relation)
这表明每个SKU对应的具体规格。

id sku_id spec_value_id
1 1 1
2 1 3
3 2 2
4 2 4
5 3 2
6 3 5
在这个例子中,我们可以看到:

sku_id为1的商品是红色、S尺寸的T恤,售价99元,库存100件。
sku_id为2的商品是蓝色、M尺寸的T恤,售价也是99元,但库存150件。
sku_id为3的商品是蓝色、L尺寸的T恤,售价稍高一些,为109元,库存200件。
这样的设计允许系统灵活处理各种规格组合,并且可以很容易地扩展到支持更多种类的规格(例如材质、样式等),同时也方便管理和查询不同规格组合的价格和库存信息。

如果你想按某个字段(如customer_id)分组,并且只选择每个组的最新记录,你可以使用GROUP BY结合子查询和ORDER BY以及LIMIT来实现。

以下是一个具体的例子,假设你有一个名为orders的表,包含customer_id、order_date和order_amount三个字段,你想按customer_id分组并只获取每个客户的最新订单:

sql
SELECT customer_id, order_date, order_amount
FROM (

SELECT customer_id, order_date, order_amount,  
       ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) as rn  
FROM orders  

) as subquery
WHERE rn = 1;
在这个查询中,我们使用了窗口函数ROW_NUMBER()来为每个customer_id分组内的记录分配一个行号。PARTITION BY customer_id确保行号是在每个customer_id的分组内重新开始计算的,而ORDER BY order_date DESC则确保最新的订单(即日期最晚的订单)被赋予行号1。

外部查询则选择了子查询中行号为1的记录,这样就只包含了每个客户的最新订单。

如果你的数据库不支持窗口函数,你也可以使用自连接和分组的方法来实现类似的效果:

sql
SELECT o1.customer_id, o1.order_date, o1.order_amount
FROM orders o1
LEFT JOIN orders o2

ON o1.customer_id = o2.customer_id AND o1.order_date < o2.order_date  

WHERE o2.order_date IS NULL;
在这个查询中,我们通过左连接orders表到它自己,基于customer_id和order_date来找出每个客户的最新订单。左连接会保留左表(o1)的所有记录,而WHERE子句中的o2.order_date IS NULL条件则确保只选择了在右表(o2)中没有找到更晚日期记录的记录,即每个客户的最新订单。

这两种方法都可以实现按客户分组并选择每个客户的最新订单的目的。选择哪种方法取决于你的数据库是否支持窗口函数以及你的个人偏好。

DROP PROCEDURE
IF EXISTS test_data_subject;

DELIMITER $$
CREATE PROCEDURE test_data_subject()
BEGIN

-- 定义变量
DECLARE i INT UNSIGNED DEFAULT 175;  -- 1是变量可以写10000
-- 循环次数
WHILE i <= 214 DO                                        -- i是变量可以 <10000

insert into intelligencevillage.renthouse_new_examination_subject (examination_id,subject_id) VALUES (28,i);

    SELECT i;
    SET i = i+1;
END WHILE;

END $$

CALL test_data_subject();