Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在内部完全联接后联接多个表?_Sql_Postgresql - Fatal编程技术网

Sql 如何在内部完全联接后联接多个表?

Sql 如何在内部完全联接后联接多个表?,sql,postgresql,Sql,Postgresql,我目前有一个SQL,其中我返回一个表,其中包含我传递给每个like的每个字符串的第一个实例,并按产品价格(最便宜的)和产品是否有库存订购。结果也应该是,对于同类产品中的每一个产品,都应该只有一个产品 例如,下表: name | price | id | stock | detail_id goat milk 1L | 100 | 1 | 1 | uuu-1 normal milk | 200 | 2 | 3 | uuu-2 dark

我目前有一个SQL,其中我返回一个表,其中包含我传递给每个like的每个字符串的第一个实例,并按产品价格(最便宜的)和产品是否有库存订购。结果也应该是,对于同类产品中的每一个产品,都应该只有一个产品

例如,下表:

name            | price | id | stock | detail_id
goat milk 1L    | 100   | 1  | 1     | uuu-1
normal milk     | 200   | 2  | 3     | uuu-2
dark chocolate  | 300   | 3  | 1     | uuu-3
normal chocolate| 100   | 4  | 55    | uuu-4
我会得到回报:

name            | price | id
goat milk 1L    | 100   | 1
normal chocolate| 100   | 4
我用来构建它的查询是这样的:

SELECT coalesce( t1."id", t2."id" ) as id,
           coalesce( t1."name", t2."name" ) as name,
           coalesce( t1."price", t2."price" ) as price
    FROM (
    SELECT id, name, price
    FROM public.product
    Where LOWER(name) like '% milk %' AND stock >0
    ORDER BY price
    LIMIT 1) t1
    FULL JOIN (
    SELECT id, name, price
    FROM public.product
    Where LOWER(name) like '% chocolate %' AND stock >0
    ORDER BY price
    LIMIT 1) t2
    ON t1."id" = t2."id"
问题是,在另一个表中,我有另一个键,叫做
allowed\u to\u use

id_use | allowed_to_use
uuu-1  | true
uuu-2  | true
uuu-3  | true
uuu-4  | false
如果
allowed\u-to\u-use
为真,我如何将此表连接到第一个表(join-id\u-use with-detail\u-id),以便能够显示产品

预期的结果将是:

name            | price | id
goat milk 1L    | 100   | 1
dark chocolate  | 300   | 3

一种方法是使用
exists
,在两个子查询中包含
详细信息_id
,并在外部查询中换行,然后检查该id是否存在并允许使用,如下所示:

select
  Coalesce( t1."id", t2."id" ) as id,
  Coalesce( t1."name", t2."name" ) as name,
  Coalesce( t1."price", t2."price" ) as price
from
(
    select * from 
     (
        select id, name, price, detail_id
        from public.product
        where Lower(name) like '% milk %' and stock >0
        order by price
        Limit 1
    ) t1
    full join (
        select id, name, price, detail_id
        from public.product
        where Lower(name) like '% chocolate %' and stock >0
        order by price
        Limit 1
    ) t2 on t1."id" = t2."id"
)t
where exists (select * from allowed_to_use a where a.id_use=t.detail_id and a.allowed_to_use='true')

您可以在sql中添加多个联接,但在您的情况下,不需要第一个联接

SELECT DISTINCT name,price,id FROM product JOIN allowed_to_use ON detail_id=id_use WHERE (LOWER(name) like '% milk %' OR LOWER(name) like '% chocolate %') AND stock >0 AND allowed_to_use;
假设所有产品都出现在两个表中


如果不使用LEFT JOIN,并决定在允许使用未定义的情况下执行什么操作。

这会导致错误:表“t1”的子句条目中缺少。问题是,我希望为我在like中使用的每个产品返回精确的一个匹配项。是的,在这种情况下,我只想返回结果的前两次出现。例如,如果前两个是牛奶,我不会对巧克力那样的表返回响应。好了,你必须加入第二个表的2倍,即t1和t2,我写我的新解决方案我想这正是我需要的,我唯一剩下的问题是,如果我想选择错误的表,而不是使用allowed_to_use=true,我应该改变什么?不是操作员-不是t11。全部降低到使用它工作得很好。谢谢,这是解决方案。最后一件事,如果你能帮我的话,有没有办法让它更“干净”,例如,想象一下,如果我喜欢t1,t2…t20,我将不得不进行20次左连接?也许,接受我的第一个答案并选择DISTINCT。。。我更正了我的第一篇帖子,请测试一下,让我们知道您希望如何处理两杯牛奶或两块巧克力价格相等的情况?如果它们都有相同的最低价格,也许你想全部退货?
SELECT coalesce( t1."id", t2."id" ) as id,
           coalesce( t1."name", t2."name" ) as name,
           coalesce( t1."price", t2."price" ) as price
    FROM (
    SELECT id, name, price
    FROM public.product
    Where LOWER(name) like '% milk %' AND stock >0
    ORDER BY price
    LIMIT 1) t1
    FULL JOIN (
    SELECT id, name, price
    FROM public.product
    Where LOWER(name) like '% chocolate %' AND stock >0
    ORDER BY price
    LIMIT 1) t2
    ON t1."id" = t2."id"
    LEFT JOIN allowed_to_use t11 ON t1.detail_id=t11.id_use
    LEFT JOIN allowed_to_use t12 ON t2.detail_id=t12.id_use
    WHERE coalesce(t11.allowed_to_use,t12.allowed_to_use);