Mysql 如何合并2个表中的3个查询。(确定日期的最小行差并显示2个表中的所有字段)
我有两张桌子 法律表格,包含两个字段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 这是你需要的吗 我不确定您是如何构建数据库的,所以我重新创建了它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 | +--------+-----------+ +-------+-------------+-------------+--
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;