按值对选择

时间:2016-05-26 12:17:17

标签: mysql

我有一张桌子(有多行),为了简化起见,请考虑这样:

Table: data
+---+--------+-------+-----+---------+
|id | name   |objId  |src  | type    |
+---+--------+-------+-----+---------+

在此表中,可以是同一name的多个条目,但是,只有一个条目应具有descriptor类型。 descriptor类型的那个指定了src列中的默认来源。

我想要一个查询,考虑到我知道每个名称的默认src,从data表中获取具有该src的条目。

一种解决方案是这样的: SELECT * FROM data WHERE (objId=<id1> AND type=<dflt1>) OR (objId=<id2> AND type=<dflt2>) OR ... OR (objId=<idN> AND type=<dfltN>) AND type<>descriptor

但是,我想知道是否有更简单(更快)的方法。

example:
+---+--------+-------+-----+----------+
|id | name   |objId  |src  | type     |
+---+--------+-------+-----+----------+
|1  | file1  | 1     | srv |descriptor|
+---+--------+-------+-----+----------+
|2  | file 1 | 1     | srv |data      |
+---+--------+-------+-----+----------+
|3  | file 1 | 1     | srv |data      |
+---+--------+-------+-----+----------+
|4  | file 1 | 1     | lcl |data      |
+---+--------+-------+-----+----------+
|5  | file 2 | 2     | lcl |descriptor|
+---+--------+-------+-----+----------+
|6  | file 2 | 2     | srv |data      |
+---+--------+-------+-----+----------+
|7  | file 2 | 2     | lcl |data      |
+---+--------+-------+-----+----------+

Query should return entries with IDs: 2, 3, 7

感谢。

4 个答案:

答案 0 :(得分:0)

   SELECT * FROM data 
    WHERE (objId,type) in (select objid,type from data where type<>'descriptor') 

在“in”子句

中添加id和dflt的所有组合

答案 1 :(得分:0)

这样的事情:

SELECT t2.*
FROM mytable AS t1
JOIN mytable AS t2 ON t1.objId = t2.objId AND t1.id  <> t2.id AND t1.src = t2.src
WHERE t1.type = 'descriptor'

Demo here

答案 2 :(得分:0)

一种解决方案是使用子查询将data中的记录限制为仅src值与每个对象组的描述符记录中的src值匹配的记录:

SELECT t1.*
FROM data t1
INNER JOIN
(
    SELECT objId, src
    FROM data
    WHERE type = 'descriptor'
) t2
    ON t1.src = t2.src AND t1.objId = t2.objId AND t1.type != 'descriptor'

请按照以下链接查看正在运行的演示:

SQLFiddle

答案 3 :(得分:0)

考虑规范化你的表格,再也不会遇到类似的问题。

objects

| objId |   name | defaultSrc |
|-------|--------|------------|
|     1 | file 1 |        srv |
|     2 | file 2 |        lcl |

data

| id | objId | src |
|----|-------|-----|
|  2 |     1 | srv |
|  3 |     1 | srv |
|  4 |     1 | lcl |
|  6 |     2 | srv |
|  7 |     2 | lcl |

然后你的查询将是:

select o.name, d.* 
from objects o 
join data d
    on  d.objId = o.objId 
    and d.src   = o.defaultSrc;

结果:

|   name | id | objId | src |
|--------|----|-------|-----|
| file 1 |  2 |     1 | srv |
| file 1 |  3 |     1 | srv |
| file 2 |  7 |     2 | lcl |

sqlfiddle

通过这种方式,您不仅可以获得更简单的查询,还可以节省磁盘/内存空间,并且(更重要的是)具有更少的IO。另外,添加适当的外键可以确保数据的完整性。