Mysql 如何合并2个表中的3个查询。(确定日期的最小行差并显示2个表中的所有字段)

Mysql 如何合并2个表中的3个查询。(确定日期的最小行差并显示2个表中的所有字段),mysql,sql,Mysql,Sql,我有两张桌子 法律表格,包含两个字段ARP和法律日期 +--------+-----------+ | ARP | legaldate | +--------+-----------+ | 71698 | 1/22/2016 | | 82501 | 4/28/2016 | | 103451 | 5/22/2016 | | 1111 | 1/2/2016 | +--------+-----------+ +-------+-------------+-------------+--

我有两张桌子

法律表格,包含两个字段ARP和法律日期

+--------+-----------+ | ARP | legaldate | +--------+-----------+ | 71698 | 1/22/2016 | | 82501 | 4/28/2016 | | 103451 | 5/22/2016 | | 1111 | 1/2/2016 | +--------+-----------+ +-------+-------------+-------------+-------------+ |ARP |录取日期|法定日期|日期差异| +-------+-------------+-------------+-------------+ | 71698 | 1/19/2016 | 1/22/2016 | 3 | | 82501 | 4/28/2016 | 4/28/2016 | 0 | | 1111 | 9/2/2016 | 1/2/2016 | 244 | +-------+-------------+-------------+-------------+ 我只想通过在两个表上运行一个查询来获得最终结果(唯一的ARP,在法定日期和录取日期之间具有最小日期差异)

谢谢

p.D

这是你需要的吗

我不确定您是如何构建数据库的,所以我重新创建了它

      DROP DATABASE LegalDB;
            CREATE DATABASE LegalDB;
            SHOW DATABASES ;
            USE LegalDB;

            CREATE TABLE Legal (
              legARP INT NOT NULL,
              legLegalDate DATE NOT NULL,
              PRIMARY KEY (legARP)
            );

            CREATE TABLE Intake(
              intIntake INT NOT NULL,
              intARP INT NOT NULL,
              intIntakeDate DATE NOT NULL,
              PRIMARY KEY (intIntake)
            );

            INSERT INTO Legal
                     (legARP, legLegalDate)
                   VALUES
                     (71698, '2016-01-22'),
                     (82501, '2016-04-28'),
                     (103451, '2016-05-22'),
                     (1111, '2016-01-02');

            INSERT INTO Intake
                          (intIntake, intARP, intIntakeDate)
                   VALUES
                     (615729,71698 ,'2015-12-09'),
                     (615891, 71698, '2015-12-10'),
                     (620697, 71698 , '2016-01-19' ),
                     (621681, 71698 , '2016-01-26'),
                     (621711, 71698 , '2016-01-26'),
                     (630455, 82501, '2016-04-28'),
                     (634946, 82501 , '2016-03-30'),
                     (123009, 1111, '2016-09-02');



   -- --------------------------------------
   -- this query SHOWS +/- sign
   -- --------------------------------------             
   SELECT * FROM (SELECT legARP, 
        (SELECT datediff(intIntakeDate, legLegalDate)) as dateDifference
        FROM Legal
        RIGHT JOIN Intake
        ON intARP = legARP
        ORDER BY legARP, ABS(dateDifference)) as selection
    GROUP BY legARP;


        This will produce the following:

          +--------+----------------+
          | legARP | dateDifference |
          +--------+----------------+
          |   1111 |            244 |
          |  71698 |             -3 |
          |  82501 |              0 |
          +--------+----------------+


   -- --------------------------------------
   -- this query DOES NOT show +/- sign
   -- -------------------------------------- 

SELECT * FROM (SELECT legARP, (SELECT ABS(datediff(intIntakeDate, legLegalDate))) as dateDifference
FROM Legal
RIGHT JOIN Intake
ON intARP = legARP
ORDER BY legARP, dateDifference) AS SELECTION
GROUP BY legARP;

 This will produce the following:

      +--------+----------------+
      | legARP | dateDifference |
      +--------+----------------+
      |   1111 |            244 |
      |  71698 |              3 |
      |  82501 |              0 |
      +--------+----------------+
通过添加显示的日期进行编辑

SELECT * FROM (SELECT legARP, intIntakeDate, legLegalDate, 
      (SELECT ABS(datediff(intIntakeDate, legLegalDate))) 
             as dateDifference
       FROM Legal
       RIGHT JOIN Intake
       ON intARP = legARP
       ORDER BY legARP, dateDifference) AS SELECTION
GROUP BY legARP;
这将产生所需的精确输出:

+--------+---------------+--------------+----------------+
| legARP | intIntakeDate | legLegalDate | dateDifference |
+--------+---------------+--------------+----------------+
|   1111 | 2016-09-02    | 2016-01-02   |            244 |
|  71698 | 2016-01-19    | 2016-01-22   |              3 |
|  82501 | 2016-04-28    | 2016-04-28   |              0 |
+--------+---------------+--------------+----------------+
请注意,问题中显示的日期不是标准日期。
日期应存储为YYYY-MM-DD,如Mysql手册所述

Mysql缺少分析功能,如
行号
。这使得在MySQL中执行此类任务变得困难,并且查询速度相当慢

我看到MySQL在一个查询中有两种方法可以做到这一点。哪一个更快取决于桌子的大小和其他一些因素

1) 最小日期差异是指不存在较小日期差异的日期:

select
  l.arp,
  i.intakedate,
  l.legaldate,
  abs(datediff(l.legaldate, i.intakedate)) as datediff
from legal l
join intake i on i.arp = l.arp
where not exists
(
  select *
  from intake i2
  where i2.arp = i.arp
  and abs(datediff(l.legaldate, i2.intakedate)) < abs(datediff(l.legaldate, i.intakedate))
);

欢迎来到堆栈溢出!您可以先学习并创建一个示例。这使我们更容易帮助您。这是一种奇怪的SQL语法。这些非标准括号中的名字我只知道从SQL Server和MS Access。表名和列名之间的感叹号表示再次使用MS Access。从另一个日期中减去一个日期在某些DBMS(例如Oracle)中是有效的,但当我在MySQL中尝试这个方法时,也不起作用。你确定你在使用MySQL吗?
SELECT DISTINCTROW [legal].ARP, Min(Abs([legal]!legaldate-Intake![Intake Date])) AS datediff
FROM Intake INNER JOIN legal ON Intake.ARP=[legal].ARP
GROUP BY [legal].ARP;
+-------+-----------+ | ARP | datediff | +-------+-----------+ | 1111 | 244 | | 71698 | 3 | | 82501 | 0 | +-------+-----------+
SELECT [intake-risk].legal.ARP, [intake-risk].[Intake Date], [intake-risk].legaldate, Mindatediff.DateDiff
FROM Mindatediff INNER JOIN [intake-risk] ON (Mindatediff.ARP = [intake-risk].Intake.ARP) AND (Mindatediff.datediff = [intake-risk].diff);
+-------+-------------+-------------+-------------+ | ARP | Intake Date | legaldate | DateDiff | +-------+-------------+-------------+-------------+ | 71698 | 1/19/2016 | 1/22/2016 | 3 | | 82501 | 4/28/2016 | 4/28/2016 | 0 | | 1111 | 9/2/2016 | 1/2/2016 | 244 | +-------+-------------+-------------+-------------+
      DROP DATABASE LegalDB;
            CREATE DATABASE LegalDB;
            SHOW DATABASES ;
            USE LegalDB;

            CREATE TABLE Legal (
              legARP INT NOT NULL,
              legLegalDate DATE NOT NULL,
              PRIMARY KEY (legARP)
            );

            CREATE TABLE Intake(
              intIntake INT NOT NULL,
              intARP INT NOT NULL,
              intIntakeDate DATE NOT NULL,
              PRIMARY KEY (intIntake)
            );

            INSERT INTO Legal
                     (legARP, legLegalDate)
                   VALUES
                     (71698, '2016-01-22'),
                     (82501, '2016-04-28'),
                     (103451, '2016-05-22'),
                     (1111, '2016-01-02');

            INSERT INTO Intake
                          (intIntake, intARP, intIntakeDate)
                   VALUES
                     (615729,71698 ,'2015-12-09'),
                     (615891, 71698, '2015-12-10'),
                     (620697, 71698 , '2016-01-19' ),
                     (621681, 71698 , '2016-01-26'),
                     (621711, 71698 , '2016-01-26'),
                     (630455, 82501, '2016-04-28'),
                     (634946, 82501 , '2016-03-30'),
                     (123009, 1111, '2016-09-02');



   -- --------------------------------------
   -- this query SHOWS +/- sign
   -- --------------------------------------             
   SELECT * FROM (SELECT legARP, 
        (SELECT datediff(intIntakeDate, legLegalDate)) as dateDifference
        FROM Legal
        RIGHT JOIN Intake
        ON intARP = legARP
        ORDER BY legARP, ABS(dateDifference)) as selection
    GROUP BY legARP;


        This will produce the following:

          +--------+----------------+
          | legARP | dateDifference |
          +--------+----------------+
          |   1111 |            244 |
          |  71698 |             -3 |
          |  82501 |              0 |
          +--------+----------------+


   -- --------------------------------------
   -- this query DOES NOT show +/- sign
   -- -------------------------------------- 

SELECT * FROM (SELECT legARP, (SELECT ABS(datediff(intIntakeDate, legLegalDate))) as dateDifference
FROM Legal
RIGHT JOIN Intake
ON intARP = legARP
ORDER BY legARP, dateDifference) AS SELECTION
GROUP BY legARP;

 This will produce the following:

      +--------+----------------+
      | legARP | dateDifference |
      +--------+----------------+
      |   1111 |            244 |
      |  71698 |              3 |
      |  82501 |              0 |
      +--------+----------------+
SELECT * FROM (SELECT legARP, intIntakeDate, legLegalDate, 
      (SELECT ABS(datediff(intIntakeDate, legLegalDate))) 
             as dateDifference
       FROM Legal
       RIGHT JOIN Intake
       ON intARP = legARP
       ORDER BY legARP, dateDifference) AS SELECTION
GROUP BY legARP;
+--------+---------------+--------------+----------------+
| legARP | intIntakeDate | legLegalDate | dateDifference |
+--------+---------------+--------------+----------------+
|   1111 | 2016-09-02    | 2016-01-02   |            244 |
|  71698 | 2016-01-19    | 2016-01-22   |              3 |
|  82501 | 2016-04-28    | 2016-04-28   |              0 |
+--------+---------------+--------------+----------------+
select
  l.arp,
  i.intakedate,
  l.legaldate,
  abs(datediff(l.legaldate, i.intakedate)) as datediff
from legal l
join intake i on i.arp = l.arp
where not exists
(
  select *
  from intake i2
  where i2.arp = i.arp
  and abs(datediff(l.legaldate, i2.intakedate)) < abs(datediff(l.legaldate, i.intakedate))
);
select
  agg.arp,
  i2.intakedate,
  agg.legaldate,
  agg.datediff
from 
(
  select
    l.arp,
    l.legaldate,
    min(abs(datediff(l.legaldate, i1.intakedate))) as datediff
  from legal l
  join intake i1 on i1.arp = l.arp
  group by l.arp, l.legaldate
) agg
join intake i2 on i2.arp = agg.arp 
               and abs(datediff(agg.legaldate, i2.intakedate)) = agg.datediff;