简体   繁体   中英

How to query duplicated rows according to column value?

I'm trying to figure out how to duplicate my rows based on the pass and fail column. Below is the table that I've done querying so far.

在此处输入图像描述

The code for the query is shown below. I'm querying from a json.

SELECT
    to_date(LotSummary ->> 'Start', 'HH24:MI:SS DD/MM/YY')AS "Date",
    Machine AS "Machine",
    LotSummary ->> 'Pass' AS "Pass",
    LotSummary ->> 'Fail' AS "Fail"
FROM
(
    SELECT
        CASE
            WHEN jsonb_typeof(json_data->'OEESummary'->'LotSummary'->'Lot') = 'array'
            THEN
                jsonb_array_elements(cast(json_data->'OEESummary'->'LotSummary'->'Lot' AS JSONB))
            ELSE
                json_data->'OEESummary'->'LotSummary'->'Lot'
            END
        AS LotSummary,
        json_data->'OEESummary'->>'MachineID' AS Machine
    FROM
    (
        SELECT
        jsonb_array_elements(cast(json_data->>'body' AS JSONB)) AS json_data
      FROM data
    )t
    WHERE
       json_data ->> 'file_name' = 'OEE.xml'
)a
WHERE
    to_date(LotSummary ->> 'Start', 'HH24:MI:SS DD/MM/YY') IS NOT NULL

So let's say I want to query it as duplicates to separate Pass and Fail values just like:

+----------------------------+--------------+------+------+
|            Date            |   Machine    | Pass | Fail |
+----------------------------+--------------+------+------+
| "2019-08-04T16:00:00.000Z" | TRS1000i-082 | 5    | NULL |
| "2019-08-04T16:00:00.000Z" | TRS1000i-082 | NULL | 2    |
| "2019-07-01T16:00:00.000Z" | TRS1000i-001 | 0    | NULL |
| "2019-07-01T16:00:00.000Z" | TRS1000i-001 | NULL | 0    |
| "2019-07-01T16:00:00.000Z" | TRS1000i-001 | 20   | NULL |
| "2019-07-01T16:00:00.000Z" | TRS1000i-001 | NULL | 0    |
+----------------------------+--------------+------+------+

Just in case you need the json formats (Do note it's not the exact one, but the format is correct):

{
  "body": [
    {
      "file_name": "OEE.xml",
      "OEESummary": {
        "MachineID": "TRS1000i-012",
        "LotSummary": {
          "Lot": [
            {
              "@i": "0",
              "Start": "14:52:16 15/08/19",
              "Pass": "3",
              "Fail": "0"
            },
            {
              "@i": "1",
              "Start": "15:40:41 15/08/19",
              "Pass": "3",
              "Fail": "0"
            }
          ]
        },
        "Utilisation": [
          "0:01:42:48",
          "19.04%"
        ],
        "MTTR": "--",
        "IdleTime": "0:07:16:39",
        "MUBA": "57",
        "OEE": "60.55%"
      }
    }
  ],
  "header": {
    "json_metadata_revision": "v1.0.0",
    "json_metadata_datetime_creation": "14-OCT-2019_14:55:57",
    "json_metadata_uuid": "14102019145557_65b425d8-09e5-48ec-be85-e69d9a50d2e3",
    "json_metadata_type": "mvst_xml_to_json"
  }
}

Do help if you know any techniques I could use to solve this issue. Your help is greatly appreciated. Thank youu.

With your table, you can use a lateral join:

select t.date, t.machine, v.pass, v.fail
from t cross join lateral
     (values (t.pass, null), (null, t.fail)) v(pass, fail);

I'm not quite sure what your query has to do with the question. But you can define it as a CTE and then use the results for t .

In the top of your result set, its just union query:

  WITH A AS(
  Select 1 id , 'TRS1000i-082' as Machine    , 5 pass, 2 fail union all
  Select 2 id , 'TRS1000i-001' as Machine    , 0 pass, 0 fail union all
  Select 3 id , 'TRS1000i-001' as Machine    , 20 pass, 0 fail 
  )
  SELECT ID
     ,MACHINE
     ,pass
     ,null fail
  FROM a
UNION ALL
  SELECT ID
     ,MACHINE
     ,null pass
     ,fail fail
  FROM a
  order by ID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM