sql查询有两个表,需要在其中一个表中搜索特定的和多个列值

zpqajqem  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(305)

我需要编写一个包含下面两个示例表的复杂查询,我正在努力理解如何正确构造查询。
表格结构如下,并附有示例数据:

  1. Table 1:
  2. ID | Type | Size
  3. A123 | Block | Medium
  4. C368 | Square | Large
  5. X634 | Triangle | Small
  6. K623 | Square | Small
  1. Table 2:
  2. ID | Code | Description | Price
  3. A123 | C06 | Sensitive Material | 99.99
  4. A123 | H66 | Heavy Grade | 12.76
  5. A123 | U74 | Pink Hue | 299.99
  6. C368 | H66 | Heavy Grade | 12.76
  7. C368 | G66 | Green Hue | 499.99
  8. C368 | C06 | Sensitive Material | 99.99
  9. C368 | K79 | Clear Glass | 59.99
  10. X634 | G66 | Green Hue | 499.99
  11. X634 | K79 | Clear Glass | 59.99
  12. X634 | Z63 | Enterprise Class | 999.99
  13. K623 | K79 | Clear Glass | 59.99
  14. K623 | G66 | Green Hue | 499.99
  15. K623 | X57 | Extra Piping | 199.99

查询应基于 Type 列,然后在 ID 表2的第列。查询的目标是搜索表1中具有特定属性的所有ID Code 表2中的列组合。
对于type=square和both(code=g66和code=k79),最终输出应该是这样的表:

  1. ID
  2. C368
  3. K623

应该返回这两个id,因为它们在上面的伪查询中都有两个选项代码。
如何使用这两个表来组合这个结果?下面是我编写的两个初始查询,它们都不会产生正确的结果。如您所见,我尝试了in运算符和=/和/或运算符。
尝试1(似乎适用于一个代码,但不是>1个代码):

  1. select distinct ID
  2. from
  3. (
  4. SELECT shapes.ID, details.code, details.description
  5. FROM db.table2 details
  6. JOIN db.table1 shapes
  7. ON details.VIN = shapes.VIN
  8. WHERE shape.type='Square'
  9. ) src
  10. where code IN ("G66", "K79")
  11. -- where code = "G66" AND code = "K79" (Produces zero results)
  12. -- where code = "G66" OR code = "K79" (Produces incorrect results)

尝试2(似乎适用于一个代码,但不是>1个代码):

  1. SELECT distinct ID
  2. FROM db.table2 details
  3. WHERE ID IN
  4. (
  5. SELECT ID FROM db.table1 shapes
  6. WHERE shapes.type='Square'
  7. ) AND code IN ("G66", "K79")
  8. -- AND code = "G66" AND code = "K79" (produces zero results)
  9. -- AND code = "G66" OR code = "K79" (Produces incorrect results)

谢谢

g6ll5ycj

g6ll5ycj1#

每当您遇到与“i need the ids from this table where is one row that value a and another row that value b and both rows that the same id”类似的问题时,您需要选择与您的条件匹配的所有行,对它们进行分组,然后对它们进行计数,并且只使用具有匹配计数的行:

  1. SELECT t2.id
  2. FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
  3. WHERE t1.type = 'square' and t2.code IN ('G66', 'K79')
  4. GROUP BY t2.id
  5. HAVING COUNT(*) = 2

如果有一些虚假的结果,比如两行是g66,没有行是k79,那么这个简单的计数将失败。相反,我们可以使用min和max查看值(如果是2):

  1. SELECT t2.id
  2. FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
  3. WHERE t1.type = 'square' and t2.code IN ('G66', 'K79')
  4. GROUP BY t2.id
  5. HAVING MIN(t2.code) = 'G66' AND MAX(t2.code) = 'K79'

它的工作原理是因为按字母顺序g66小于k79,所以g66将是最小的一个
如果我们有3个必须指定的值,我们可以做一些技巧,比如把所有的代码都变成一个数字,并要求求和。我将使用基数2:

  1. SELECT t2.id
  2. FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
  3. WHERE t1.type = 'square' and t2.code IN ('G66', 'K79', 'X99')
  4. GROUP BY t2.id
  5. HAVING SUM(CASE t2.Code WHEN 'G66' THEN 1 WHEN 'K79' THEN 2 WHEN 'X99' THEN 4 END) = 7

如果我们将它们Map到1、2和4,那么生成7的唯一方法(如果值是唯一的)就是每个值都有一个。如果可能有7个g66而其他的都没有,给出一个虚假的结果,那么我们可能必须单独计算它们:

  1. SELECT t2.id
  2. FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id
  3. WHERE t1.type = 'square' and t2.code IN ('G66', 'K79', 'X99')
  4. GROUP BY t2.id
  5. HAVING
  6. SUM(CASE t2.code WHEN 'G66' THEN 1 ELSE 0 END) = 1 AND
  7. SUM(CASE t2.code WHEN 'K79' THEN 1 ELSE 0 END) = 1 AND
  8. SUM(CASE t2.code WHEN 'X99' THEN 1 ELSE 0 END) = 1
展开查看全部
pobjuy32

pobjuy322#

我是这么想的。
用where子句过滤t1中的数据,然后连接t2,两次,每次都按条件过滤,使g66和k79在同一个表中(两个不同的连接)

  1. Select t1.ID
  2. from t1
  3. inner join t2 as t2_G66 on t1.ID = t2_G66.ID
  4. inner join t2 as t2_K79 on t1.ID = t2_K79.ID
  5. where t1.Type = 'Square' and
  6. t2_G66.Code = 'G66' and
  7. t2_K79.Code = 'K79'

这是小提琴

qjp7pelc

qjp7pelc3#

因为表1和表2是按id关联的,所以在获取了具有我们要查找的类型的相关行之后,不能对表1中的id使用内部联接吗?
我想我们可以先做一个查询来获取所有具有相关类型的行,然后运行一个 INNER JOIN 获取具有我们关心的id的共享行。
最后,我们可以按代码列对结果进行分组?
也许像这样的办法行得通

  1. SELECT * FROM db.table1 WHERE db.table1.type = "whatever"
  2. INNER JOIN db.table2 ON db.table1.id = db.table2.id
  3. GROUP BY db.table2.code HAVING COUNT(*) >= 1
  4. AND db.table2.code IN ("code_1, code_2, code_3")

我刚刚开始sql,所以我希望这是希望!
p、 我意识到我并没有涵盖你们的条件,让代码成为你们关心的代码子集的一员。所以我认为这可能管用。

相关问题