关于 SQL 查询的建议(我的似乎过于复杂,甚至会吐出标量子查询错误)

Advice on SQL query (mine seems to overcomplicate and even spits out scalar subquery error)

我正在使用 SQL 开发人员 (oracle sql)。

下面的查询吐出错误: “一行 returns 多于一行的子查询”

查询逻辑请指教。我不指望任何人为我解决它。告诉我我的想法哪里错了。

给定一个 table,它给出以下数据:

+---------+------+---------+------------+-----------+----------+
| PS_NAME | SIDE | WO_NUM  | LOT_PREFIX | PLAIN_LOT | AB_SPLIT |
+---------+------+---------+------------+-----------+----------+
| ...     | ..   | ...     |    ...     |  ...      |     .    |
| ANW216  | TO   | 5041092 |    VNAN    |  ANW216   |     x    |
| ANW217  | TO   | 4897524 |    VNAN    |  ANW217   |     x    |
| ANW218  | TO   | 5041093 |    VNAN    |  ANW218   |     x    |
| ANW219  | TO   | 5064069 |    VNAN    |  ANW219   |     x    |
| ANW219A | TO   | 5064097 |    VNAN    |  ANW219A  |     A    |
| ANW220  | TO   | 5064070 |    VNAN    |  ANW220   |     x    |
| ANW220A | TO   | 5064098 |    VNAN    |  ANW220A  |     A    |
| ANW221  | TO   | 5064071 |    VNAN    |  ANW221   |     x    |
| ANW221A | TO   | 5064099 |    VNAN    |  ANW221A  |     A    |
| ANW222  | TO   | 5064072 |    VNAN    |  ANW222   |     x    |
| ANW223  | TO   | 5062459 |    VNAN    |  ANW223   |     x    |
| ...     | ..   | ...     |    ...     |  ...      |     .    |
+---------+------+---------+------------+-----------+----------+

想要的结果:

+---------+------+---------+------------+-----------+----------+
| PS_NAME | SIDE | WO_NUM  | LOT_PREFIX | PLAIN_LOT | AB_SPLIT |
+---------+------+---------+------------+-----------+----------+
| ...     | ..   | ...     |    ...     |  ...      |     .    |
| ANW216  | TO   | 5041092 |    VNAN    |  ANW216   |     x    |
| ANW217  | TO   | 4897524 |    VNAN    |  ANW217   |     x    |
| ANW218  | TO   | 5041093 |    VNAN    |  ANW218   |     x    |
| ANW219A | TO   | 5064097 |    VNAN    |  ANW219A  |     A    |
| ANW220A | TO   | 5064098 |    VNAN    |  ANW220A  |     A    |
| ANW221A | TO   | 5064099 |    VNAN    |  ANW221A  |     A    |
| ANW222  | TO   | 5064072 |    VNAN    |  ANW222   |     x    |
| ANW223  | TO   | 5062459 |    VNAN    |  ANW223   |     x    |
| ...     | ..   | ...     |    ...     |  ...      |     .    |
+---------+------+---------+------------+-----------+----------+

我想达到的效果:如果带A的有很多,带A的就给我;并且不显示非A; 所以,只给我 ANW219A(忽略 ANW219)

这是我的查询背后的逻辑:

"Give me the PS_NAME,
   Case, when there is a truncated name (in table t2)
      which is also in table t3
   Then give me this lot with letter A
   Else give me the regular (non-A) lot"

从第一个角度来看,这个问题似乎很简单,但我只是没有得到我想去的地方。而且,我的直觉告诉我,我的查询可能太复杂了。

SELECT
            CASE
                WHEN (
                    SELECT
                        substr(lot, 0, length(lot) - 1)
                    FROM
                        table t2
                    WHERE
                            t1.wo_num = t2.wo_num
                        AND lot_prefix <> 'x'
                        AND side = 'TO'
                        AND ab_split <> 'x'
                ) IN (
                    SELECT
                        lot
                    FROM
                        table t3
                    WHERE
                            t1.wo_num = t3.wo_num
                        AND lot_prefix <> 'x'
                        AND side = 'TO'
                        AND ab_split = 'x'
                )
        --lot
                 THEN
            --t2.lot
                    'THEN'
                ELSE
            --t1.lot
                    'else'
            END ps_name
        FROM
            (
                SELECT
                    lot,
                    ps_date,
                    mcu,
                    wo_num,
                    srp3,
                    lot_core,
                    lot_prefix,
                    plain_lot,
                    ab_split
                FROM
                    table
                WHERE
                        lot_prefix <> 'x'
                    AND side = 'TO'
                    AND ab_split = 'x'
            ) t1

这可能会成功,具体取决于 WHERE 子句如何与 table 中的其他行交互:

SELECT * 
FROM (
    SELECT t1.*,
        row_number() over (partition by substr(ps_name, 1, 6) order by substr(ps_name, 1, 6), wo_num desc) as rn
    FROM "table" t1
    WHERE Side = 'TO' AND lot_prefix<>'X'
) t
WHERE rn=1

或者更明确地匹配声明的逻辑:

SELECT * 
FROM (
    SELECT t1.*,
        row_number() over (
          partition by substr(ps_name, 1, 6) 
          order by case when substr(ps_name 7, 1) = 'A' then 0 else 1 end
         ) as rn
    FROM "table" t1
    WHERE Side = 'TO' AND lot_prefix<>'X'
) t
WHERE rn=1