寻找正确的查询

时间:2019-03-27 08:09:35

标签: mysql sql laravel

我有一个名为document_histories的表。我的桌子的一个例子:

id   | assembly_order_id | document_type | document_year | document_number | document_date | created_at          | updated_at
2839 | 1287              | ub            | 2019          | 928             | 2019-03-18    | 2019-03-18 14:00:27 | 2019-03-18 14:00:27
2861 | 1287              | us            | 2019          | 881             | 2019-03-19    | 2019-03-19 16:31:06 | 2019-03-19 16:31:06
2862 | 1287              | us            | 2019          | 882             | 2019-03-20    | 2019-03-20 16:39:06 | 2019-03-20 16:39:06
2896 | 1287              | ul            | 2019          | 932             | 2019-03-25    | 2019-03-25 10:55:10 | 2019-03-25 10:55:10

我想做的是列出从一个文档到另一个文档所花费的时间。 例如: #2839是我们的起点(ub)。 document_date是2019-03-18。现在,我希望该行中最低的document_date具有相同的assembly_order_id,并且其中document_typeus

所以我们会有这样的东西:

id   | assembly_order_id | document_type | document_year | document_number | document_date | created_at          | updated_at           | *date_diff*
2839 | 1287              | ub            | 2019          | 928             | 2019-03-18    | 2019-03-18 14:00:27 | 2019-03-18 14:00:27  | *1* (2019-03-19 - 2019-03-18)

这只是1个时差,但我还希望us(最低日期)和ul(最新/最高日期)之间以及ub(最低日期)和ul(最新/最高日期)

我尝试了以下查询,但是由于它在'time_until_assembly','assembly_time'和'total_delivery_time'列中返回了大量空值,因此无法完全正常工作

SELECT
    ub.*,
    @time_until_assembly:= DATEDIFF((SELECT us.document_date FROM document_histories us WHERE us.document_type = 'us' AND us.assembly_order_id = ub.assembly_order_id LIMIT 1), ub.document_date) AS time_until_assembly,
    DATEDIFF((SELECT ul.document_date FROM document_histories ul WHERE ul.document_type = 'ul' AND ul.assembly_order_id = ub.assembly_order_id LIMIT 1), @time_until_assembly) AS assembly_time,
    DATEDIFF((SELECT dl.document_date FROM document_histories dl WHERE dl.document_type = 'ul' AND dl.assembly_order_id = ub.assembly_order_id LIMIT 1), ub.document_date) AS total_delivery_time
FROM
    document_histories ub
WHERE
    ub.document_type = 'ub'

由于没有正确的输出,我尝试了另一种方法:

SELECT
    ub.*,
    ub.document_date as ub_date,
    us.document_date as us_date,
    ul.document_date as ul_date,

    DATEDIFF(ul.document_date, ub.document_date) as total_days_delivery,
    DATEDIFF(ul.document_date, us.document_date) as total_days_assembly,
    DATEDIFF(us.document_date, ub.document_date) as total_days_order
FROM
    document_histories ub, document_histories us, document_histories ul
WHERE
    ub.document_type = 'ub' AND
    us.document_type = 'us' AND
    ul.document_type = 'ul' AND
    us.assembly_order_id = ub.assembly_order_id AND
    ul.assembly_order_id = ub.assembly_order_id
ORDER BY
    ub.document_date ASC,
    us.document_date ASC,
    ul.document_date DESC

但这会返回具有重复值的列表,这些列表具有不同的total_值。

2 个答案:

答案 0 :(得分:1)

尝试使用外部联接:

SELECT
  ub.*,
  ub.document_date as ub_date,
  us.document_date as us_date,
  ul.document_date as ul_date,
  DATEDIFF(ul.document_date, ub.document_date) as total_days_delivery,
  DATEDIFF(ul.document_date, us.document_date) as total_days_assembly,
  DATEDIFF(us.document_date, ub.document_date) as total_days_order
FROM
  document_histories ub
  LEFT JOIN document_histories us ON us.assembly_order_id = ub.assembly_order_id AND us.document_type = 'us'
  LEFT JOIN document_histories ul ON ul.assembly_order_id = ub.assembly_order_id AND ul.document_type = 'ul'
WHERE
  ub.document_type = 'ub'

编辑汇总:

SELECT
  ub.*,
  ub.document_date as ub_date,
  us.document_date as us_date,
  ul.document_date as ul_date,
  DATEDIFF(ul.document_date, ub.document_date) as total_days_delivery,
  DATEDIFF(ul.document_date, us.document_date) as total_days_assembly,
  DATEDIFF(us.document_date, ub.document_date) as total_days_order
FROM
  document_histories ub
  LEFT JOIN (
    SELECT 
      assembly_order_id,document_date 
    FROM document_histories 
    WHERE 
      document_type = 'us' 
    ORDER BY 
      document_date ASC -- Change ASC/DESC respectively
    LIMIT 1) us ON us.assembly_order_id = ub.assembly_order_id
  LEFT JOIN (
    SELECT 
      assembly_order_id,document_date 
    FROM document_histories 
    WHERE 
      document_type = 'ul' 
    ORDER BY 
      document_date DESC -- Change ASC/DESC respectively
    LIMIT 1) ul ON ul.assembly_order_id = ub.assembly_order_id
WHERE
  ub.document_type = 'ub'

答案 1 :(得分:0)

基于以上答案,我进行了以下查询以完全实现我的目标:

SELECT
    ub.id, ub.assembly_order_id, ub.document_type, ub.document_year, ub.document_number,    ub.document_date as order_date,    ul.document_date as delivery_date,    us.document_date as assembly_date,    DATEDIFF(ul.document_date, ub.document_date) as delivery_days,    DATEDIFF(ul.document_date, us.document_date) as assembly_days
FROM
    `document_histories` ub
INNER JOIN (
    SELECT
        assembly_order_id, document_date
    FROM
        `document_histories`
    WHERE document_type = 'ul'
    GROUP BY assembly_order_id
    ORDER BY document_date DESC
) ul ON ul.assembly_order_id = ub.assembly_order_id
LEFT JOIN (
    SELECT
        assembly_order_id, document_date
    FROM
        document_histories
    WHERE document_type = 'us'
    GROUP BY assembly_order_id
    ORDER BY document_date ASC
) us ON us.assembly_order_id = ub.assembly_order_id
WHERE
    ub.document_type = 'ub'
ORDER BY `delivery_days`  DESC

非常感谢您