Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用SQL中的相关子查询的情况下获取最早的日期?_Sql_Oracle_Greatest N Per Group_Correlated Subquery - Fatal编程技术网

如何在不使用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处于活动状态时检查执行时,有一个可测量的节省。讽刺的是,也许是我的记忆有问题。