如何在不使用SQL中的相关子查询的情况下获取最早的日期?
下面的代码列出了所有发票,我只想要来自供应商的最旧发票:如何在不使用SQL中的相关子查询的情况下获取最早的日期?,sql,oracle,greatest-n-per-group,correlated-subquery,Sql,Oracle,Greatest N Per Group,Correlated Subquery,下面的代码列出了所有发票,我只想要来自供应商的最旧发票: SELECT DISTINCT vendor_name, i.invoice_number AS OLDEST_INVOICE, MIN(i.invoice_date), i.invoice_total FROM vendors v JOIN invoices i ON i.vendor_id = v.vendor_id GROUP BY vendor_name, invoice_number, invoice_total OR
SELECT DISTINCT vendor_name, i.invoice_number AS OLDEST_INVOICE,
MIN(i.invoice_date), i.invoice_total
FROM vendors v
JOIN invoices i
ON i.vendor_id = v.vendor_id
GROUP BY vendor_name, invoice_number, invoice_total
ORDER BY MIN(i.invoice_date);
请尝试以下方法:
SELECT DISTINCT
v.vendor_name,
i.invoice_number AS OLDEST_INVOICE,
i2.MinDate,
i.invoice_total
FROM vendors v
INNER JOIN invoices i ON i.vendor_id = v.vendor_id
INNER JOIN
(
SELECT
invoice_number ,
MIN(i.invoice_date) MinDate
FROM invoices
GROUP BY invoice_number
) i2 ON i.invoice_number = i2.invoice_number
AND i.invoice_date = i2.MinDate
ORDER BY i2.MinDate;
你不在这里工作吗
SELECT DISTINCT vendor_name, i.invoice_number AS OLDEST_INVOICE,
MIN(i.invoice_date), i.invoice_total
FROM vendors v
JOIN invoices i
ON i.vendor_id = v.vendor_id
GROUP BY vendor_name, invoice_number, invoice_total
HAVING i.invoice_date = MIN (i.invoice_date)
ORDER BY MIN(i.invoice_date);
TDQD的时间-测试驱动的查询设计 每个供应商的发票最短日期如下所示:
SELECT vendor_id, MIN(invoice_date) AS invoice_date
FROM invoices
GROUP BY vendor_id
如果发票日期为不含时间成分的真实日期,则在供应商开具发票的第一天可能发送了多张发票,则相应的最小发票编号;如果日期包含时间成分,则可能不需要第二分钟,即:
SELECT vendor_id, MIN(invoice_number) AS invoice_number
FROM invoices AS i
JOIN (SELECT vendor_id, MIN(invoice_date) AS invoice_date
FROM invoices
GROUP BY vendor_id
) AS j ON j.vendor_id = i.vendor_id AND j.invoice_date = i.invoice_date
GROUP BY vendor_id
您可以将此表达式与其他表联接以满足查询要求:
SELECT v.*, i.*
FROM vendors AS v
JOIN (SELECT vendor_id, MIN(invoice_number) AS invoice_number
FROM invoices AS i
JOIN (SELECT vendor_id, MIN(invoice_date) AS invoice_date
FROM invoices
GROUP BY vendor_id
) AS j ON j.vendor_id = i.vendor_id AND j.invoice_date = i.invoice_date
GROUP BY vendor_id
) AS inv_info ON v.vendor_id = inv_info.vendor_id
JOIN invoices AS i ON i.invoice_number = inv_info.invoice_number
毫无疑问,还有其他的设计方法。请注意,这些子查询都不是相关子查询
TDQD完全是名义上的;没有一个DBMS在检查这些查询是否在语法上有效时遇到问题,更不用说返回正确的答案了。奥托,这是一种标准和技术
如果您喜欢在GROUP BY子句中列出许多列,您可以让inv_info子查询返回相关的发票列,而不必最终连接到发票。我不喜欢写太多的列名——但如果我担心性能,我会衡量一下,看它是否有显著的不同
您可能会发现,OLAP功能/查询可以更快地完成这项工作。我们将使用行编号按供应商日期对发票进行排序,然后仅选择每个供应商最早的发票:
SELECT vendor_name, invoice_number AS oldest_invoice, invoice_date, invoice_total
FROM vendors v
INNER JOIN (SELECT invoices.*,
ROW_NUMBER() OVER (PARTITION BY vendor_id ORDER BY invoice_date ASC)
AS rn
FROM invoices) i
ON i.vendor_id = v.vendor_id
AND
i.rn = 1;
这个代码列出了所有的发票,我只想从一个vendoris组按vendor_name ORDER BY。。。您想要什么?您的SQL引擎支持行号吗?我想在发票日期之前返回每个供应商和订单的所有第一批发票,而不使用相关子查询否,我有此代码,但我想修改它,使其不使用相关子查询选择v.vendor\u name,i.发票号作为最早的发票,i.发票日期,i.来自供应商的发票总额v加入i.供应商id=v.供应商id上的发票i和i.发票日期=从其中供应商id=v.供应商id按i.发票日期订购的发票中选择最小发票日期@MarcGordon-我在回答中发布的查询与此查询相同,没有相关子查询。它给了我以下错误报告:SQL错误:ORA-00933:SQL命令未正确结束00933。00000-SQL命令未正确结束此答案中的子查询不是相关子查询。它可能不是正确的子查询,但它不是相关子查询。抱歉,我无法测试,因为我懒得键入表定义。没有子查询,该技术将无法工作,而且实际上不使用HAVING子句。我通常首选使用Min或Max而不是Row\U Number,由于内存效率更高-RDBMS不必维护发票的排序列表,在这种情况下,它可以从中选择具有最小排序的发票,它只需存储每个窗口的最小值或最大值。@davidardridge,分区的最小值/最大值解决方案会是什么样子,假设发票编号不一定形成递增顺序,例如,“OCT099”在“NOV001”之前?选择供应商名称、发票编号作为最早的发票、发票日期、供应商v的发票总额,选择发票。*,根据发票i中的供应商id最小发票日期每个供应商划分的最小发票日期,其中i.vendor\u id=v.vendor\u id和i.invoice\u date=i.min\u发票日期_vendor@DavidAldridge,右和+1。现在,你怎么打破领带?oracle是否提高了内存效率?乍一看,您的派生表i仍然选择每一行,它只是将最小日期附加到每一行。如果可能出现平局的情况,那么最好对某个唯一的行施加进一步的排序,而不是接受伪随机行,如果只是为了记录问题。是的,仍然必须选择每一行,保存来自查询执行,而不必维护所有行的数字排名。实际上,也许我指的是CPU节省而不是内存节省,但正如我所记得的,在V$SQL\u WORKAREA\u处于活动状态时检查执行时,有一个可测量的节省。讽刺的是,也许是我的记忆有问题。