用 SQL 迭代匹配数据?

发布于 2024-12-17 20:09:42 字数 1070 浏览 1 评论 0原文

我正在努力解决一个查询,并且我已经被困了几天而不知道这是否可能。

我有一个如下的结果集:

ID  ;CASE;LINE;QTY;ORDER;CODE
1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2710;   1;  1;55555;C
9628;2708;   1;  1;55555;C
9628;2708;   2;  1;66666;
9628;2710;   2;  1;66666;
9628;2710;   3;  1;55555;C
9628;2708;   3;  1;55555;C

从这些行中,我想得到这些:

1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2710;   1;  1;55555;C
9628;2708;   3;  1;55555;C

或者:

1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2708;   1;  1;55555;C
9628;2710;   3;  1;55555;C

,即,我想过滤掉 CODE null 的结果集(我可以做到这一点)并希望将案例与行匹配(这是我遇到了问题)。

问题是我与歧视没有任何关系。 CASE 2708 与 LINE 3 或 1 匹配并不重要,但 CASE 2710 需要与不同的 LINE 匹配。

这在 Java 或 C++ 等语言中非常容易,但由于我无法声明变量或列表,所以我不知道如何将 LINE“标记”为选定状态。

我也无法使用存储过程。我开始认为这是不可能完成的,但也许有人可以提供一些线索。

提前致谢!

I'm struggling with a query, and I've been stuck for a couple of days without figuring out if this is even possible.

I have a resultset like the following:

ID  ;CASE;LINE;QTY;ORDER;CODE
1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2710;   1;  1;55555;C
9628;2708;   1;  1;55555;C
9628;2708;   2;  1;66666;
9628;2710;   2;  1;66666;
9628;2710;   3;  1;55555;C
9628;2708;   3;  1;55555;C

From those lines, I want to get these:

1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2710;   1;  1;55555;C
9628;2708;   3;  1;55555;C

Or:

1446;2725;   1;  1;33333;A
1446;2724;   1;  1;33333;A
0430;2545;   1;  2;44444;B
0430;2547;   1;  2;44444;B
9628;2708;   1;  1;55555;C
9628;2710;   3;  1;55555;C

, i.e., I want to filter out the ones with CODE null (I can do that) and want to match cases with lines (this is where I'm having problems).

The thing is that I don't have any relation to discriminate. It doesn't matter that CASE 2708 is matched to LINE 3 or 1, but CASE 2710 needs to be matched to a different LINE.

This would be very easy in a language like Java or C++, but since I cannot declare variables or lists, I don't know how to "mark" a LINE as selected.

I cannot use stored procedures too. I'm starting to think is not possible to accomplish, but maybe someone can throw a bit of light.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴者 2024-12-24 20:09:42

编辑

第一版本没有解决问题。

ordercasePostgreSQL 中的保留字。不要将它们用作标识符!在我的示例中,我重命名为 ordcas

WITH x AS (
    SELECT id, qty, ord, code
          ,min(line) AS line1
          ,max(line) AS line2
          ,min(cas)  AS cas1
          ,max(cas)  AS cas2
    FROM   tbl
    WHERE  code IS NOT NULL
    GROUP  BY 1,2,3,4
    )
SELECT id, cas1, line2, qty, ord, code
FROM   x
UNION  ALL  -- only add more rows, where 
SELECT id, cas2, line1, qty, ord, code
FROM   x
WHERE  cas1 <> cas2 AND line1 <> line2
ORDER  BY code, 1,2,3,4,5;

这假设每个 code 最多有两个不同的 linecas,并且其他列不会添加更多变体。
它产生问题中演示的结果。

Edit

First version did not address question.

order and case are reserved words in PostgreSQL. Do not use them as identifiers! I renamed to ord and cas in my example.

WITH x AS (
    SELECT id, qty, ord, code
          ,min(line) AS line1
          ,max(line) AS line2
          ,min(cas)  AS cas1
          ,max(cas)  AS cas2
    FROM   tbl
    WHERE  code IS NOT NULL
    GROUP  BY 1,2,3,4
    )
SELECT id, cas1, line2, qty, ord, code
FROM   x
UNION  ALL  -- only add more rows, where 
SELECT id, cas2, line1, qty, ord, code
FROM   x
WHERE  cas1 <> cas2 AND line1 <> line2
ORDER  BY code, 1,2,3,4,5;

This assumes a maximum of two different line or cas per code and that other columns do not add more variations.
It produces the result demonstrated in the question.

城歌 2024-12-24 20:09:42

尽管尚不清楚您的数据是否始终会按 ID 生成值对,但以下内容将产生与指定相同的输出:

SELECT ID,
       CASE M.AGG WHEN "MIN" THEN MIN(M."CASE")
            ELSE MAX(M."CASE")
       END AS "CASE",
       CASE M.AGG WHEN "MIN" THEN MIN(M.LINE)
            ELSE MAX(M.LINE)
       END AS LINE,
       CASE M.AGG WHEN "MIN" THEN MIN(M.QTY)
            ELSE MAX(M.QTY)
       END AS QTY,
       CASE M.AGG WHEN "MIN" THEN MIN(M."ORDER")
            ELSE MAX(M."ORDER")
       END AS "ORDER",
       CASE M.AGG WHEN "MIN" THEN MIN(M."CODE")
            ELSE MAX(M."CODE")
       END AS "CODE"
FROM MYTABLE M
CROSS JOIN (SELECT "MIN" AGG UNION SELECT "MAX") A
WHERE M.CODE IS NOT NULL
GROUP BY M.ID, A.AGG

The following will produce the same output as specified, although it isn't clear whether your data will always produce pairs of values by ID:

SELECT ID,
       CASE M.AGG WHEN "MIN" THEN MIN(M."CASE")
            ELSE MAX(M."CASE")
       END AS "CASE",
       CASE M.AGG WHEN "MIN" THEN MIN(M.LINE)
            ELSE MAX(M.LINE)
       END AS LINE,
       CASE M.AGG WHEN "MIN" THEN MIN(M.QTY)
            ELSE MAX(M.QTY)
       END AS QTY,
       CASE M.AGG WHEN "MIN" THEN MIN(M."ORDER")
            ELSE MAX(M."ORDER")
       END AS "ORDER",
       CASE M.AGG WHEN "MIN" THEN MIN(M."CODE")
            ELSE MAX(M."CODE")
       END AS "CODE"
FROM MYTABLE M
CROSS JOIN (SELECT "MIN" AGG UNION SELECT "MAX") A
WHERE M.CODE IS NOT NULL
GROUP BY M.ID, A.AGG
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文