获取具有多个条件的行

mqkwyuun  于 2021-07-24  发布在  Java
关注(0)|答案(3)|浏览(273)

下面是我的postgres表:
表格:

  1. +------+-----------------+---------+
  2. | sku | properties | value |
  3. |------+-----------------+---------|
  4. | 1 | Family_ID | 21 |
  5. | 1 | Class_ID | 21 |
  6. | 2 | Family_ID | 20 |
  7. | 2 | Class_ID | 21 |
  8. | 3 | Family_ID | 21 |
  9. | 3 | Class_ID | 21 |
  10. +------+-----------------+---------+

如何查询是否要从 Family_ID 以及 Class_ID21 .
预期返回值:

  1. +------+-----------------+---------+
  2. | sku | properties | value |
  3. |------+-----------------+---------|
  4. | 1 | Family_ID | 21 |
  5. | 1 | Class_ID | 21 |
  6. | 3 | Family_ID | 21 |
  7. | 3 | Class_ID | 21 |
  8. +------+-----------------+---------+

如何查询是否要从 Family_ID20 以及 Class_ID21 .
预期返回值:

  1. +------+-----------------+---------+
  2. | sku | properties | value |
  3. |------+-----------------+---------|
  4. | 2 | Family_ID | 20 |
  5. | 2 | Class_ID | 21 |
  6. +------+-----------------+---------+
mefy6pfw

mefy6pfw1#

此查询:

  1. select sku
  2. from tablename
  3. group by sku
  4. having
  5. max(case when properties = 'Family_ID' then value end) = 21
  6. and
  7. max(case when properties = 'Class_ID' then value end) = 21

返回所有 sku 满足你的条件的,你可以和操作符一起使用 IN 这样地:

  1. select * from tablename
  2. where sku in (
  3. select sku
  4. from tablename
  5. group by sku
  6. having
  7. max(case when properties = 'Family_ID' then value end) = 21
  8. and
  9. max(case when properties = 'Class_ID' then value end) = 21
  10. )

也可以使用max()窗口函数:

  1. select t.sku, t.properties, t.value
  2. from (
  3. select *,
  4. max(case when properties = 'Family_ID' then value end) over (partition by sku) family_id,
  5. max(case when properties = 'Class_ID' then value end) over (partition by sku) class_id
  6. from tablename
  7. ) t
  8. where t.family_id = 21 and t.class_id = 21

请看演示。
结果:

  1. > sku | properties | value
  2. > --: | :--------- | ----:
  3. > 1 | Family_ID | 21
  4. > 1 | Class_ID | 21
  5. > 3 | Family_ID | 21
  6. > 3 | Class_ID | 21
展开查看全部
r55awzrz

r55awzrz2#

要跨行操作,您需要分组,但这里最简单的事情(考虑到您似乎希望此主题有更多的变体)可能是数据透视:

  1. WITH x as(
  2. SELECT f.sku, c.value as class_value, f.value as family_value
  3. FROM
  4. (select sku, value FROM table WHERE properties = 'family_id') f
  5. INNER JOIN
  6. (select sku, value FROM table WHERE properties = 'class_id') c
  7. ON f.sku = c.sku
  8. )

现在可以使用where子句,如normal:

  1. SELECT * FROM x WHERE family_value = 20 and class_value = 21

如果需要以列格式返回数据,可以再次取消打印:

  1. SELECT
  2. sku,
  3. 'family_id' as properties,
  4. family_value as value
  5. FROM
  6. x
  7. UNION ALL
  8. SELECT
  9. sku,
  10. 'class_id' as properties,
  11. class_value as value
  12. FROM
  13. x

但只处理数据透视形式的数据可能更容易。
我自己不一定要这么做,但是如果您习惯于常规的连接、联合和其他类似的“典型”数据库操作,那么理解这种形式的数据透视就容易多了,所以我推荐您使用它,因为您可能会发现它更易于维护和扩展。执行透视的条件聚合可能更有效,但维护起来更复杂:

  1. WITH X as (
  2. SELECT
  3. sku,
  4. MAX(CASE WHEN properties = 'Family_ID' THEN value END) as family_value,
  5. MAX(CASE WHEN properties = 'Class_ID' THEN value END) as class_value
  6. FROM
  7. table
  8. GROUP BY sku
  9. )

案件蔓延时 value 根据 properties 价值观。groupby/max然后折叠行,删除空值,留下唯一的sku和指定列中的值(根据它们是哪种值)

展开查看全部
vql8enpb

vql8enpb3#

  1. --case 1
  2. select *
  3. from tbl t
  4. where exists (select *
  5. from tbl t1
  6. where t1.sku=t.sku
  7. and t1.properties='Family_ID'
  8. and t1.value=21)
  9. and exists (select *
  10. from tbl t1
  11. where t1.sku=t.sku
  12. and t1.properties='Class_ID'
  13. and t1.value=21)
  14. --case 2
  15. select *
  16. from tbl t
  17. where exists (select *
  18. from tbl t1
  19. where t1.sku=t.sku
  20. and t1.properties='Family_ID'
  21. and t1.value=20)
  22. and exists (select *
  23. from tbl t1
  24. where t1.sku=t.sku
  25. and t1.properties='Class_ID'
  26. and t1.value=21)
展开查看全部

相关问题