我有2张桌子
表1:
id | user_id | pattern
1 | 3 | ^1212.*
2 | 3 | ^192.*
3 | 4 | ^20.*
表2:
id |pattern | start_date | comment
1 |^1212.* | 2014-03-22 20:10:13 | India-Gujarat
2 |^1212.* | 2014-03-24 20:10:13 | India -Maharastra
3 |^1212.* | 2014-03-25 20:10:13 | India -uttar pradesh
4 |^1212.* | 2014-03-27 20:10:13 | India -Madhya pradesh
5 |^1212.* | 2014-03-29 20:10:13 | India -Rajasthan
6 |^192.* | 2014-03-22 20:10:13 | Africa
7 |^20.* | 2014-03-22 20:10:13 | Indonesia- first
8 |^20.* | 2014-03-26 20:10:13 | indonesia -second
9 |^1212.* | 2014-03-22 20:10:13 | India- kerala
10 |^13.* | 2014-03-22 20:10:13 | Usa
11 |^13.* | 2014-03-22 20:12:13 | usa
12 |^14.* | 2014-03-22 20:10:13 | U.k
必填项:
id | pattern | start_date
8 |^20.* | 2014-03-26 20:10:13 | Indonesia-first
10 | ^13.* | 2014-03-22 20:12:13 | USA
12 | ^14.* | 2014-03-22 20:10:13 | U.k
输出要求:
我尝试使用3次执行查询的PHP代码,需要很长时间
所以可以在postgresql中使用单个查询
答案 0 :(得分:0)
这应该可以解决问题:
SELECT DISTINCT a.pattern
FROM table2 a
LEFT OUTER JOIN table1 b ON a.pattern = b.pattern AND b.user_id = {current_user}
WHERE b.id IS NULL
将表2中的所有行与表1中的所有行连接起来,基于它们的模式,并且只有它属于当前用户。然后你只选择那些无法连接的那些。
根据您的评论,我不再100%确定您的意思。一种方法是将DISTINCT
添加到上面的查询中。
另一种变体是
SELECT DISTINCT pattern FROM table2
EXCEPT
SELECT pattern FROM table1 WHERE user_id = {current user}
根据您想要来自表2最新一行的其他信息的信息,此查询可能会对您有所帮助:
SELECT a.* FROM table2 a
INNER JOIN (
SELECT pattern, MAX(start_date) AS max_start_date
FROM table2
GROUP BY pattern
) mostrecent
ON a.pattern = mostrecent.pattern AND a.start_date = mostrecent.max_start_date
LEFT OUTER JOIN table1 b ON a.pattern = b.pattern AND b.user_id = {current_user}
WHERE b.id IS NULL
上半部分请求table2中所有最近的行。下半部分(以LEFT OUTER JOIN
开头)将此连接到表1,并且(如前所述)仅选择那些在table1中没有行的行。
另一个专门用于Postgresql 8.4+的解决方案是
WITH mostrecent AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY pattern ORDER BY start_date DESC) AS rank
FROM table2
)
SELECT a.*
FROM mostrecent a
LEFT OUTER JOIN table1 b ON a.pattern = b.pattern AND b.user_id = {current_user}
WHERE b.id IS NULL AND a.rank = 1