关于 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
我正在使用 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