2016-09-16 35 views
1

数据库引擎我使用:在PostgreSQL 9.5.2需要有效的SQL从另一个物化视图加入行数物化视图

我试图做

我有在我的PostgreSQL以下两个物化视图:

1)state_vendors_mat_view

 
vendor_id sol_id states_list total_revenue 
--------- ------ ----------- ------------- 
1234   abc  CA, AZ   23000.00 
5678   abc  TX, FL   12000.00 
9012   def  AZ, TX   67000.00 

2)interested_vendors_mat_view

 
sol_id vendor_id  
------ --------- 
abc  1234 
def  5678 

我想要查询state_vendors_mat_view对于给定的sol_id(例如“ABC”);然而,我想知道,对于结果中的每个vendor_id,是否将vendor_id映射到interested_vendors_mat_view中的sol_id。如果它被映射,我想要一个布尔值true;否则,我想要一个布尔值为false。

此外,我希望这个查询尽可能高效。对于state_vendors_mat_view的结果中的每个记录,我不想在interested_vendors_mat_view上运行选择。

预期的效果

例如,如果我想有一个sol_id = “ABC” 的所有供应商的话,我想要的结果看起来像:

 
vendor_id is_interested sol_id states_list total_revenue 
--------- ------------- ------ ----------- ------------- 
1234   True   abc  CA, AZ   23000.00 
5678   False   abc  TX, FL   12000.00 

注意

  • vendor_id = 1234的记录在is_interested列中的布尔值为True,因为interested_ vendors_mat_view有一个映射1234和“abc”的记录。
  • vendor_id = 5678的记录在is_interested列中的布尔值为False,因为interested_vendors_mat_view没有映射5678和“abc”的记录。

问题我已经看了

SQL我已经试过

SELECT 
vendor_id, 
CASE 
    WHEN ((SELECT count(*) FROM interested_vendors_mat_view iv 
      WHERE sol_id = 'abc' and iv.vendor_id = state.vendor_id) = 0) 
    THEN false 
    ELSE true 
END AS is_interested, 
sol_id, 
states_list, 
total_revenue 
FROM state_vendors_mat_view state WHERE sol_id = 'abc'; 

,试图让刚刚正确的行数,我也试着:

SELECT 
    state.vendor_id, 
    state.sol_id, 
    count(*) 
FROM state_vendors_mat_view state 
JOIN interested_vendors_mat_view iv ON (iv.vendor_id = state.vendor_id) 
WHERE state.sol_id = 'abc' 
GROUP BY state.vendor_id, state.sol_id 

这些都不给我正确的解决方案。

任何帮助,非常感谢。谢谢。

+0

如何你的查询不起作用?什么是正确的结果集和你得到的结果集? –

+0

@GordonLinoff第一个查询在is_interested列的每一行都给了我一个True。第二个查询给了我state_vendors_mat_view中vendor_id的总行数。我现在会尝试你的SQL。谢谢。 – Aperix

回答

1

我不知道为什么你的查询不起作用,但这可能是因为子查询中的比较使用snid而不是sol_id(根据问题中的数据格式应该会产生错误)。

在任何情况下,查询会更简单地使用exists表示:

SELECT sv.*, 
     (exists (select 1 
       from interested_vendors_mat_view iv 
       where iv.vendor_id = sv.vendor_id and iv.sol_id = 'abc' 
       ) 
     ) as is_interested 
FROM state_vendors_mat_view sv 
WHERE sv.sol_id = 'abc'; 
+0

这个SQL工作!非常感谢!顺便说一句:我的意思是'snid'是'sol_id'(更新了我的问题)。 – Aperix

2

考虑一个LEFT JOIN查询与条件列计算is_interested,避免任何子查询的需要:

SELECT s.vendor_id, 
     CASE WHEN i.sol_id = 'abc' 
      THEN TRUE 
      ELSE FALSE 
     END AS is_interested, 
     s.sol_id, 
     s.states_list, 
     s.total_revenue 
FROM state_vendors_mat_view s 
LEFT JOIN interested_vendors_mat_view i 
ON (s.sol_id = i.sol_id) AND (s.vendor_id = i.vendor_id) 
WHERE s.sol_id = 'abc' 
+0

我也会尝试这个SQL。谢谢。 – Aperix

+0

该SQL也适用。您在CASE声明中只是错过了前面的一个开放原文。谢谢。 – Aperix

+0

太棒了!良好的捕获 - 事实上,不需要任何括号。让我们希望未来的读者得到帮助。 – Parfait