问题描述
SELECT phone_number,3,toppings,crust
FROM pizza p
INNER JOIN lemon l ON p.seven_digit = l.code
UNION
SELECT phone_number,crust
FROM pizza p
INNER JOIN lemon l ON p.six_digit = l.code;
如您所见,它是: 查询A INNER JOIN子表UNION查询B INNER JOIN子表
我想要查询A或查询B的结果,但不能同时获取两者。如果两者都存在,则返回A的结果。
在此示例中,l.code具有6或7位数字。
现在我得到的结果翻倍了。
更新
所以我将帮助做出更好的描述:
CREATE TABLE not_on_lrn_table_3_22 (
phone_number bigint NOT NULL,seven_digit int DEFAULT NULL,six_digit int DEFAULT NULL,PRIMARY KEY (phone_number)
)
CREATE TABLE lerg (
code int NOT NULL,status varchar(3) DEFAULT NULL
)
INSERT INTO not_on_lrn_table_3_22
VALUES
(2222226433,2222226,222222),(2222222222,2222222,(2222263445,2222263,222226),(2222283445,2222283,222228);
INSERT INTO lerg
VALUES
(222222,'AAA'),(2222226,'BBB'),(2222223,'CCC'),(2222281,'DDD'),(2222263,'EEE')
我想要not_on_lrn_table_3_22中每一行的结果(如果有匹配项)。
例如, Lerg代码列的长度为6/7位。 我想查看not_on_lrn_table_3_22第一行,查找其seven_digit值,然后尝试在 lerg.code 上进行匹配,如果存在,则返回该行数据,如果不存在,请检查 > lerg.code 如果在那儿,则返回该行,如果不在那儿,则跳过该行。
想法是7位数字匹配更准确。
提供给我的解决方案是:
WITH cte1 AS (
SELECT pn.*,l.*,ROW_NUMBER() OVER (PARTITION BY pn.phone_number
ORDER BY CASE WHEN l.code = pn.seven_digit
THEN 1 ELSE 2 END) AS ord
FROM not_on_lrn_table_3_22 AS pn
JOIN lerg AS l
ON l.code IN (pn.six_digit,pn.seven_digit)
)
SELECT * FROM cte1
WHERE ord = 1
;
它可以工作,但是要花很长时间才能完成。
这是另一张图片,解释了我要实现的目标。 enter image description here
看第一行: 在第6/7列(六位数)中有代码/状态的匹配项,因此我将返回与lerg表相关的数据,其中代码= 222222。
第二行: 有2场比赛。代码/状态在第4/5/6/7列。 (七位数和六位数)。当两者都匹配时,返回与lerg表相关联的数据,其中代码为2222226。(因为它的位数更大,因此更准确)。
第三行: 第4/5列中有1个比赛。同样,因为这是7位数字,您只需在第二行做同样的事情即可。
第四行: 没有匹配项,因此不返回任何内容。
解决方法
不确定会带来多大的改善,但请尝试一下
select phone_number,coalesce(seven_digit,six_digit),coalesce(l2.status,l.status)
from not_on_lrn_table_3_22 as pn
left join lerg as l on l.code =pn.six_digit
left join lerg as l2 on l2.code=pn.seven_digit
where coalesce(l2.status,l.status) is not null;
,
假设phone_number
来自表lemon
(尽管您尚未指定属于lemon
的列,但我假设至少有lemon
中的一列SELECT子句,否则UNION将合并相同的行,并且您不会得到任何重复):
SELECT
phone_number,3,toppings,crust
FROM
(
SELECT
if(l1.phone_number is null,l2.phone_number,l1.phone_number) as phone_number,crust
FROM pizza p
LEFT JOIN lemon l1 ON p.seven_digit = l1.code
LEFT JOIN lemon l2 ON p.six_digit = l2.code
)
t
WHERE phone_number is not null;
,
SELECT phone_number,3 some_alias,3 another_alias,crust
FROM pizza p
INNER JOIN lemon l ON p.seven_digit = l.code
WHERE LENGTH(l.code) = 7
UNION ALL
SELECT phone_number,crust
FROM pizza p
INNER JOIN lemon l ON p.six_digit = l.code
WHERE LENGTH(l.code) = 6
AND NOT EXISTS (SELECT NULL
FROM pizza p
INNER JOIN lemon l ON p.seven_digit = l.code
WHERE LENGTH(l.code) = 7)
如果要最大程度地减少服务器执行的工作量,请创建并使用存储过程,而不是单个查询。