SQL在最大日期退出联接

时间:2019-09-01 09:04:56

标签: postgresql optimization sql-tuning

我有两个表: Success = 0 Bounces = 0 def SendMessage(botid, token, userid, messageid, tag): global Success global Bounces try: payload = {...} r = requests.post("...", params=payload, headers=head, timeout=2) #problem with request? pjson = json.loads(r.text) if r.status_code != 200: log(str(r.status_code) + " " + pjson["result"] + " UserID: " + UserID + "; URL: " + "..." + BotID + "/users/" + UserID + "/send; Params: " + str(payload)) Bounces += 1 return Success += 1 return except requests.exceptions.Timeout: #wait for connection to be available again! while not conn_available(): print("... Waiting for a new connection...") time.sleep(10) log("Request timed out. UserID: " + UserID + "; URL: " + "..." + BotID + "/users/" + UserID + "/send; Params: " + str(payload)) Bounces += 1 except requests.exceptions.ConnectionError: log("Unable to connect. UserID: " + UserID + "; URL: " + "..." + BotID + "/users/" + UserID + "/send; Params: " + str(payload)) Bounces += 1 except requests.exceptions.HTTPError: log("Invalid request. UserID: " + UserID + "; URL: " + "..." + BotID + "/users/" + UserID + "/send; Params: " + str(payload)) Bounces += 1 except requests.exceptions.RequestException: log("Invalid request. UserID: " + UserID + "; URL: " + "..." + BotID + "/users/" + UserID + "/send; Params: " + str(payload)) Bounces += 1 while True: newMsgsReq = "" try: #Check for new messages newMsgsReq = requests.get("...", timeout=2) if newMsgsReq.text == "false": #exit sub time.sleep(2) continue except requests.exceptions.HTTPError as errh: log("Request has failed: There was an error in the request: [" + str(errh) + "]") time.sleep(2) continue except requests.exceptions.ConnectionError as errc: log("Request has failed: check internet connection & retry: [" + str(errc) + "]") time.sleep(2) continue except requests.exceptions.Timeout as errt: log("Request has failed: check internet connection & retry: [" + str(errt) + "]") time.sleep(2) continue except requests.exceptions.RequestException as err: log("Request has failed: There was an error in the request: [" + str(err) + "]") time.sleep(2) continue #we have a message!!! #Extract BotID, Token, MessageID msgInf = newMsgsReq.text.split("|") MessageID = msgInf[0] BotID = msgInf[1] Token = msgInf[2] Tag = msgInf[3] del msgInf[0:4] suc("New message found: " + str(MessageID)) suc("Total recipients: " + str(len(msgInf))) #Begin send! Cycles = 0 TotCycles = 0 #Loop through msgInf for UserID in msgInf: #Create the thread. process = threading.Thread(target=SendMessage, args=[BotID, Token, UserID, MessageID, Tag]) process.start() TotCycles += 1 pb.print_progress_bar(TotCycles) Cycles += 1 if Cycles == 24: time.sleep(1) Cycles = 0 suc("Message " + str(MessageID) + " sent successfully (" + str(Success) + " success, " + str(Bounces) + " bounces") Success = 0 Bounces = 0 time.sleep(3) contracts

contract_descriptions上有一个名为contract_descriptions的列,它与contract_id表记录相等。

我正在尝试加入contracts上的最新记录:

contract_descriptions

它起作用了,但是它是高效的方法吗?有办法避免第二个SELECT * FROM contracts c LEFT JOIN contract_descriptions d ON d.contract_id = c.contract_id AND d.date_description = (SELECT MAX(date_description) FROM contract_descriptions t WHERE t.contract_id = c.contract_id) 吗?

2 个答案:

答案 0 :(得分:2)

您也可以使用DISTINCT ON

SELECT * FROM contracts c LEFT JOIN (
    SELECT DISTINCT ON (cd.contract_id) cd.* FROM contract_descriptions cd
    ORDER BY cd.contract_id, cd.date_description DESC
) d ON d.contract_id = c.contract_id

DISTINCT ON每个contract_id仅选择一行,而sort子句cd.date_description DESC确保它始终是最后一个描述。

性能取决于许多值(例如,表大小)。无论如何,您都应该将两种方法与EXPLAIN进行比较。

答案 1 :(得分:2)

您的查询对我来说还可以。从另一张表按某种顺序仅连接n行的一种典型方法是横向连接:

SELECT *
FROM contracts c
CROSS JOIN LATERAL
(
  SELECT *
  FROM contract_descriptions cd
  WHERE cd.contract_id = c.contract_id
  ORDER BY cd.date_description DESC
  FETCH FIRST 1 ROW ONLY
) cdlast;