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

时间:2017-01-23 01:00:11

标签: mysql sql

我有2张桌子。

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

+--------+-----------+
|  ARP   | legaldate |
+--------+-----------+
|  71698 | 1/22/2016 |
|  82501 | 4/28/2016 |
| 103451 | 5/22/2016 |
|   1111 | 1/2/2016  |
+--------+-----------+

摄取表,包含3个字段的摄入量,ARP和摄入日期

+--------+-------+------------+
| Intake |  ARP  | IntakeDate |
+--------+-------+------------+
| 615729 | 71698 | 12/9/2015  |
| 615891 | 71698 | 12/10/2015 |
| 620697 | 71698 | 1/19/2016  |
| 621681 | 71698 | 1/26/2016  |
| 621711 | 71698 | 1/26/2016  |
| 630455 | 82501 | 4/28/2016  |
| 634946 | 82501 | 3/30/2016  |
| 123009 |  1111 | 9/2/2016   |
+--------+-------+------------+

我加入两个表的ARP并查找legaldate和进入日期之间的日期差异(显示两个表格中的所有字段 - 使用查询1

我发现法定日期和入学日期之间的最小日期差异(仅显示'min diff'和'ARP') - 使用查询2

我通过日期diff / mindatediff和ARP / ARP加入查询1和查询2以获得所需结果 - 查询3 (与两个表中的所有字段的最小日期差异)

最终显示我得到(在法定日期和进入日期之间具有最短日期差异的独特ARP)

+-------+-------------+-----------+----------+
|  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 |
+-------+-------------+-----------+----------+

我运行3个查询(我发现我也可以在两个查询中得到这些结果)。 我想要有效率,并在一个查询中得到欲望结果。

我的3个查询

1)使用'摄入风险'查询

查找日期差异
SELECT Intake.Intake, legal.ARP, Intake.[Intake Date], legal.legaldate, Abs([legal]![legaldate]-[Intake]![Intake Date]) AS Diff
FROM Intake RIGHT JOIN legal ON Intake.ARP = legal.ARP;
+----------+-----------+-------------+-----------+------+
|  Intake  |    ARP    | Intake Date | legaldate | Diff |
+----------+-----------+-------------+-----------+------+
| 621711   |     71698 | 1/26/2016   | 1/22/2016 |    4 |
| 621681   |     71698 | 1/26/2016   | 1/22/2016 |    4 |
| 620697   |     71698 | 1/19/2016   | 1/22/2016 |    3 |
| 615891   |     71698 | 12/10/2015  | 1/22/2016 |   43 |
| 615729   |     71698 | 12/9/2015   | 1/22/2016 |   44 |
| 634946   |     82501 | 3/30/2016   | 4/28/2016 |   29 |
| 630455   |     82501 | 4/28/2016   | 4/28/2016 |    0 |
| Blank... |    103451 | 5/22/2016   |           |      |
| 123009   |      1111 | 9/2/2016    | 1/2/2016  |  244 |
+----------+-----------+-------------+-----------+------+

2)使用'Mindatediff'查询

查找最短日期差异
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 |
+-------+-----------+

3)查询'Mindate-legalbegin'以获得最终结果。

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 |
+-------+-------------+-------------+-------------+

我想通过在两个表上运行一个查询来获得最终结果! (在法定日期和进入日期之间具有最小日期差值的独特ARP)

由于

2 个答案:

答案 0 :(得分:0)

Pd积,

你需要的是什么?

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

      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手册https://dev.mysql.com/doc/refman/5.7/en/datetime.html

中所述。

答案 1 :(得分:0)

MySQL缺乏ROW_NUMBER等分析功能。这使得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))
);

2)选择最小日期差异并使用它来再次访问该表:

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;