【问题标题】:strange sql query implementation joining tables奇怪的sql查询实现连接表
【发布时间】:2016-06-06 22:54:39
【问题描述】:

我需要一些有关 SQL 查询的帮助。让我描述一下场景

我有三个表,dispensariesgoodsproducts

products 记录有两个fkgood_iddispensary_id,让我可以通过产品从药房访问商品。 商品还有一个属性叫name

现在我想解决的情况如下:

对于提供的一组商品名称 ([good_name1, good_name2, etc]),我想获取所有在数组中包含所有商品的药房(与这些名称匹配的商品)。

让我添加一个例子:

 good1 whose names is  good_1 belongs to dispensary1
 good1 whose names is  good_1 belongs to dispensary2
 good2 whose names is  good_2 belongs to dispensary1

所以我需要创建一个 SQL 查询,使用提供的商品数组 [good1, good2] 返回唯一的 dispesary1

提前致谢。

【问题讨论】:

    标签: sql ruby postgresql ruby-on-rails-4


    【解决方案1】:

    实现这一点的一种方法是使用INTERSECT,为每个子句生成一个集合——这意味着您必须将列表展开为 n 个查询,每个查询一个:

    SELECT dispensary.id, dispensary.name
    FROM products
    INNER JOIN goods ON goods.id = products.goods_id
    INNER JOIN dispensary ON dispensary.id = products.dispensary_id
    WHERE goods.name = 'good_1'
    INTERSECT
    SELECT dispensary.id, dispensary.name
    FROM products
    INNER JOIN goods ON goods.id = products.goods_id
    INNER JOIN dispensary ON dispensary.id = products.dispensary_id
    WHERE goods.name = 'good_2'
    INTERSECT
    SELECT dispensary.id, dispensary.name
    FROM products
    INNER JOIN goods ON goods.id = products.goods_id
    INNER JOIN dispensary ON dispensary.id = products.dispensary_id
    WHERE goods.name = 'good_3'
    

    这样,您只会得到所有集合中的结果。

    【讨论】:

      【解决方案2】:

      您可能希望将其转换为一个函数,该函数接受您所追求的商品名称项目数组。首先,我会得到正确的数据语法和格式。在查询窗口中尝试以下操作,看看它是否可以通过商品名称文本项的静态列表为您提供所需的数据。

      SELECT dispensary.id, dispensary.name
      FROM products
      LEFT JOIN goods ON goods.id = products.goods_id
      LEFT JOIN dispensary ON dispensary.id = products.dispensary_id
      WHERE goods.name IN ([good_name1, good_name2, etc])
      AND dispensary.id IS NOT NULL;
      

      编辑

      要仅返回包含数组中所有项目的药房,请尝试(来自@ErwinBrandstetter 答案PostgreSQL where all in array 的修改参考):

      CREATE OR REPLACE FUNCTION f_dispensaries_with_all_products(_user_arr string[])
        RETURNS SETOF dispensary AS
      $BODY$
      DECLARE
          _sql text := '
          SELECT d.*
          FROM   products p
          JOIN   dispensary d ON d.id = p.dispensary_id';
          i int;
      BEGIN
      
      FOREACH i IN ARRAY _user_arr LOOP
          _sql  := _sql  || '
          JOIN   goods g' || i || ' ON g|| i || '.id = p.good_id';
      END LOOP;
      
      _sql  := _sql  || '
          WHERE  d.id IS NOT NULL ';
      
      FOREACH i IN ARRAY _user_arr LOOP
          _sql  := _sql  || '
          AND    g' || i || '.name = ' || _user_arr[i];
      END LOOP;
      
      -- RAISE NOTICE '%', _sql;
      RETURN QUERY EXECUTE _sql;
      
      END;
      $BODY$ LANGUAGE plpgsql VOLATILE;
      

      【讨论】:

      • 不是我需要的,检查 IN 子句只是给我所有在我提供的阵列内有好的药房,但我需要阵列中的所有货物都属于到药房退回
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多