IN CLause中的MYSQL元组与通配符匹配

时间:2012-09-24 21:12:25

标签: mysql sql database

我有以下问题。假设我有一张包含汽车库存的表格:

VIN, MAKE, MODEL, PRICE

我还有另一个包含各种汽车类的表(例如,紧凑型,中型,SUV等)

MAKE, MODEL, CLASS
JEEP, NULL , SUV
FORD, EXPLORER, SUV
TOYOTA, YARIS, COMPACT
NULL, CUBE, COMPACT
...

我想知道如何选择某一类数据库中的所有汽车?也许,我想知道每个班级有多少车?

我可以写这样的查询。

SELECT COUNT(*) FROM CARS WHERE (MAKE, MODEL) IN (SELECT MAKE, MODEL FROM CLASSES WHERE CLASS = 'SUV')

这里的问题,我实际上无法处理我的数据中的NULL。我想说的是所有型号的JEEP都是SUV,或任何名为CUBE的MAKE车都是小型车。

如果没有冲突,可以这样做吗?我可以设置一个优先级,比如所有Porches都是CARS,除了Cayenne这是SUV之类的东西:

MAKE, MODEL, CLASS
PORCHE, NULL , CAR
PORCHE, CAYENNE, SUV

如果MySQL无法做到这一点,那么有更好的数据库技术可以做到这一点。让我们假设CLASSES表包含50K +行,CARS表包含5M +行。我正在寻找一种在数据库中执行此类查询的快速方法,而不需要在脚本中获取数百万行进行处理?如果它不仅仅是Make和Model,还有子模型,引擎等等。

另外,我简化了数据,有4级层次结构。

3 个答案:

答案 0 :(得分:1)

您可以这样编写查询:

SELECT COUNT(*)
FROM CARS c join
     classes cl
     on (c.make = cl.make or cl.make is null) and
        (c.model = cl.model or cl.model is null) and
        cl.class = 'SUV'

问题是您可能会重复。因此,更好的计数始于:

select count(distinct c.vin)
. . .

这适用于您为JEEP和CUBE提供的两个案例。

答案 1 :(得分:1)

假设对于给定的类,make和model不能同时为null。您可以使用MySQL中的ifnull()函数:

select cl.class, count(*)
from cars c inner join class cl
   on c.make = ifnull(cl.make,c.make)
   and c.model=ifnull(cl.model,c.model)
group by cl.class

您可能希望在列makesmodel上添加索引,以便更快地访问。由于classes使用内部联接的行数较少(如上所述),因此将限制返回的行数。

答案 2 :(得分:0)

SELECT s.class,COUNT(*) 来自car c,car_class s 在哪里c.make = s.make AND c.model = s.model GROUP BY s.class

应该给你类似的东西

SUV 14 紧凑32 卡车11 等