【问题标题】:Null restriction in sql in operator运算符中的 sql 中的 Null 限制
【发布时间】:2019-08-28 19:38:57
【问题描述】:

我正在寻找一个查询来一次获取多行的多列数据。

表 1. 无空值

customer, price1, price2, price3, ..., price10
Tata,     100,    200,    300,    ..., 1000
Ford,     111,    222,    333,    ..., 1388

我可以使用以下查询:

SELECT *
FROM table1
WHERE (customer,price1,price2,price3,...~price10)
IN (
(Tata,100,200,300,400,500,..~1000)
OR
(Ford,111,222,333,444,555,...~1388)

表 2:

consumer_code, price1, price2, price3, price4, …, price10
Chn,           100,    200,    (null), (null), …, 600
Hyd,           121,    378,    262,    (null), …, (null)

SQL where in 运算符不接受空值。 有什么更好的查询建议吗?

我需要一次性传递>500或1000的批量数据,以便通过使用多个select语句减少多个db操作并提高检索速度。

【问题讨论】:

  • 我不明白逻辑 - 你是说你只想要完全匹配的行,例如,如果 chn 在价格 3 中有 20 它不应该出现,或者你是说如果所有非空列匹配然后该行应该出现?
  • 请注意,数据库表不是电子表格。认真考虑您当前的模式是否适合目的。 (提示:不是)
  • @P.Salmon 是的,我需要完全匹配的行。所有列的组合
  • @strawberry 我的架构需要支持这一点。我需要传递电子表格值并验证结果。

标签: mysql sql


【解决方案1】:

Sql where in 运算符不接受空值。有什么更好的查询建议吗?

in 运算符确实接受NULL 值。它根本不认为它们是平等的。

您可以使用NULL-safe 比较,<=> 而不是IN

where (customer_code <=> 'Tata' and price1 <=> 100 and . . .
      ) or
      (customer_code <=> 'Ford' and price1 <=> 111 and . . .
      ) or

您可以在值中包含NULL

这也适用于元组,所以:

where (customer, price1, price2, price3,... ~price10)
<=> ('Tata', 100, 200, 300, 400, 500,.. ~1000) or
      (customer, price1, price2, price3,... ~price10) <=> ( . . . ) or
       . . . 

【讨论】:

  • 嗨 Lintoff 它几乎类似于 where( (customer = 'Tata', price1=100, price2=200,price3=300) 或 (customer='Tata',price1 IS NULL, price2 IS NULL , 价格 3=400))。如果我们一次提及列并将值作为元组提及,您的查询会很好
【解决方案2】:

假设您希望与输入完全匹配,您可以使用子查询作为输入并加入主表

drop table if exists t;

create table t
(mid varchar(3), p1 int,p2 int,p3 int);

insert into t values
('frd',1,2,3),
('frd',1,2,5),
('frd',1,null,3),
('chn',1,2,3);

select t.* 
from t
join (select cast('frd' as char(3)) mid, 1 p1,null p2,3 p3
        union
        select 'chn',1,2,3) s 
on  s.mid = t.mid and
        coalesce(s.p1,-1) = coalesce(t.p1,-1) and 
        coalesce(s.p2,-1)   = coalesce(t.p2,-1) and 
        coalesce(s.p3,-1)   = coalesce(t.p3,-1);


+------+------+------+------+
| mid  | p1   | p2   | p3   |
+------+------+------+------+
| frd  |    1 | NULL |    3 |
| chn  |    1 |    2 |    3 |
+------+------+------+------+
2 rows in set (0.00 sec)

您可能会遇到整理问题。从长远来看,创建一个表来保存您的条件并使用它而不是子查询可能更容易。

【讨论】:

  • 它有效。感谢您的贡献。但我不明白整理问题以及创建单独的表将如何提供帮助。如果可能的话,您能否简要解释一下或提供任何提供相关信息的链接。一次传递太多内部选择值(比如 500 左右)是否安全?
猜你喜欢
  • 2013-01-05
  • 2012-11-03
  • 1970-01-01
  • 2011-09-05
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多