V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjsxwc
V2EX  ›  程序员

应该怎么写成一句 sql

  •  
  •   zjsxwc ·
    zjsxwc · 2018-07-23 10:04:16 +08:00 · 2136 次点击
    这是一个创建于 2313 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在商品 item 表结构

    id, product_id, type, price

    一个 product 下有多个商品,商品 item 有 4 种 type 值(0,1,2,3),同一个 type 下可以有多个同样 type 与同样 product_id 的商品。

    现在有 N 个商品 id,我要根据这些商品 id,来获取这些商品的 product_id,然后根据这些 product_id 再获取 item 表里面,所有 product_id 与 4 个 type 值组合下的一个 price 最低的商品 的列表。

    目前我是这么写的

    SET session sql_mode=(SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
    
    SELECT min(price), id, product_id, type
    FROM item 
    WHERE product_id IN(
      SELECT product_id FROM item WHERE id IN (1,2,3,4,5)
    )  
    GROUP BY product_id, type
    

    应该怎么写成一句 sql ?

    6 条回复    2018-07-23 10:52:37 +08:00
    Mazexal
        1
    Mazexal  
       2018-07-23 10:07:37 +08:00
    第一, 不要把 sql 写的太复杂, 不利于复用
    第二, 复杂 sql 不便于阅读与拍错
    复杂 sql 建议拆分成简易 sql 使用事务处理
    yulitian888
        2
    yulitian888  
       2018-07-23 10:10:40 +08:00
    开窗函数了解一下?
    mokeyjay
        3
    mokeyjay  
       2018-07-23 10:12:08 +08:00
    @Mazexal #1 其实不一定,LZ 问的这题,有点类似我之前碰到的笔试题,而笔试题是不会需要你考虑这些的
    bpllzbh
        4
    bpllzbh  
       2018-07-23 10:27:31 +08:00
    需求: 有一张学生成绩表(table_score),id, 学生 id(s_id),学科 id(p_id),分数(score)这么几个字段
    会出现同一个学生同一个学科有多个分数, 这时候的需求是 取表记录 id 较大的那个筛选出来

    SELECT * FROM table_score a
    WHERE NOT EXISTS
    (SELECT 1 FROM table_score b
    WHERE a.s_id=b.s_id
    AND a.p_id=b.p_id
    AND a.id<b.id)

    ============
    可供参考
    webcoder
        5
    webcoder  
       2018-07-23 10:47:49 +08:00
    其实理论上 lz 说的方法是没问题的,只要在 product_id 作个索引,速度也不会太慢。

    但实际应用时,需要翻页的话,就要拆成两个 sql 句才行。
    第一个 SELECT distinct product_id FROM item WHERE id IN (1,2,3,4,5) limit 0,10

    注:加上 distinct 是防止重复的 product_id 出现,导致翻页出现空窗
    然后再用的
    SELECT min(price), id, product_id, type
    FROM item
    WHERE product_id IN( 第一句的结果 )
    GROUP BY product_id, type

    这样翻页的效率会高一些。
    saulshao
        6
    saulshao  
       2018-07-23 10:52:37 +08:00
    听上去不难,思路是这样的:
    1. 根据你知道的商品 ID 获取所有的 Product_id;
    2. 根据你得到的所有 PRODUCT_ID,去商品表里面按照读取 PRODUCT_ID,TYPE,PRICE。按照 PRODUCT_ID,TYPE 这 2 个字段分组,获得最小的 PRICE.
    (到这里你似乎已经实现了)
    3. 根据 2 的结果,直接用商品表读取 PRODUCT_ID,TYPE,PRICES 都和 2 的结果相等的所有行就行。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4836 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:10 · PVG 09:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.