sql - PostgreSQL 3 表连接乘法

标签 sql postgresql cartesian-product

我有 3 个表。第一个有我想要的记录。其他两个具有要应用于第一个表的类别。如果在描述中找到来自 table3 的查找值,我想返回该类别。否则,返回表 2 中的类别。我认为我的逻辑是正确的,但结果正在成倍增加。如何将结果限制为我想要的 table1 记录,但应用正确的类别?

这是我的查询示例架构。它应该只返回 table1 中类别正确的前 6 行,但它返回 10。http://sqlfiddle.com/#!15/fc6fa/49/0

SELECT table1.product_code, table1.date_signed, table1.description, 
CASE 
  WHEN lower(table1.description) LIKE ('%' || lower(table3.lookup_value) || '%') 
  THEN table3.category 
  ELSE table2.category 
END 
FROM table1 
LEFT JOIN table2 ON table2.psc_code = table1.product_code 
LEFT JOIN table3 ON table3.psc_code = table1.product_code 
WHERE date_signed = '2017-02-01';



create table table1 ( 
product_code int, 
date_signed timestamp, 
description varchar(20) 
); 

insert into table1 
(product_code, date_signed, description) 
values 
(1, '2017-02-01', 'i have a RED car'), 
(2, '2017-02-01', 'i have a blue boat'), 
(3, '2017-02-01', 'i have a dark cat'), 
(1, '2017-02-01', 'i have a green truck'), 
(2, '2017-02-01', 'i have a blue rug'), 
(3, '2017-02-01', 'i have a dark dog'), 
(1, '2017-02-02', 'i REd NO SHOW'), 
(2, '2017-02-02', 'i blue NO SHOW'), 
(3, '2017-02-02', 'i dark NO SHOW'); 

create table table2 ( 
psc_code int, 
category varchar(20) 
); 

insert into table2 
(psc_code, category) 
values 
(1, 'vehicle'), 
(2, 'vehicle'); 

create table table3 ( 
psc_code int, 
lookup_value varchar(20), 
category varchar(20) 
); 

insert into table3 
(psc_code, lookup_value, category) 
values 
(1, 'fox', 'animal'), 
(1, 'red', 'color'), 
(1, 'box', 'shipping'), 
(2, 'cat', 'animal');

最佳答案

您正在尝试将 1 连接到多,而您只需要一个值。

SELECT table1.product_code, table1.date_signed, table1.description,
CASE 
  WHEN EXISTS (select 1 from table3
               where table3.psc_code = table1.product_code and
                     lower(table1.description) LIKE ('%' || lower(table3.lookup_value) || '%')) 
  THEN (select table3.category from table3 
        where table3.psc_code = table1.product_code and
              lower(table1.description) LIKE ('%' || lower(table3.lookup_value) || '%') limit 1)
  ELSE (select table2.category
        from table2
        where table2.psc_code = table1.product_code
        limit 1)
END 
FROM table1 
WHERE date_signed = '2017-02-01';

http://rextester.com/TQIY93378

+--------------+---------------------+----------------------+----------+
| product_code |     date_signed     |      description     | category |
+--------------+---------------------+----------------------+----------+
| 1            | 01.02.2017 00:00:00 | i have a RED car     | color    |
| 2            | 01.02.2017 00:00:00 | i have a blue boat   | vehicle  |
| 3            | 01.02.2017 00:00:00 | i have a dark cat    | NULL     |
| 1            | 01.02.2017 00:00:00 | i have a green truck | vehicle  |
| 2            | 01.02.2017 00:00:00 | i have a blue rug    | vehicle  |
| 3            | 01.02.2017 00:00:00 | i have a dark dog    | NULL     |
+--------------+---------------------+----------------------+----------+

关于sql - PostgreSQL 3 表连接乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42303927/

相关文章:

mysql - 如何链接两个不同的表并更新第二个表?

sql - 根据列值排列数据

php - 我怎样才能完成这个笛卡尔乘积函数的 Objective-C 实现?

sql - 根据一组计算的时间范围 mysql 拉取平均值和计数

sql - 使用 select 将行添加到查询结果

mysql - SQL查询中的平均时间戳

postgresql - 在扣除用户余额和调用第三方服务时如何正确解释系统故障?

sql - 为什么带有 DELETE 的 PostgreSQL CTE 不起作用?

java - 获取由数组定义的动态多个集合的笛卡尔积

c# - 访问对象数组的数组的元素