基于表数据动态形成的SQL查询

时间:2019-09-15 13:54:49

标签: sql postgresql

我会使用Postgresql作为数据库,以防万一,尽管我想找到一种纯SQL方法而不是特定于Postgresql的实现。

我有大量的制造电子产品的测试数据,我想从测试中获取满足一定条件的单元数据,最好使用包含测试的单独表格每个制造步骤的标准。

举一个简单的例子,假设我在两个不同的测试步骤中检查了设备的温度和电压回读,并根据阈值进行了检查。

我们假设下面的表结构带有一组示例数据(表名“ test_data”):

temperature  voltage  step   serial_number
    25          10      1        1
    55          15      2        1
    19          17      1        2
    20          20      2        2

,让我们假设下表包含传递单位的条件(表名称“ criteria”):

column_name     lower   upper   step
temperature      20      30      1
temperature      50      60      2
   voltage       9       11      1
   voltage       14      16      2

不从条件表中读取的静态查询如下:

SELECT * FROM test_data  WHERE       
  ( test_data.step = 1 AND test_data.temperature > 20 AND test_data.temperature < 30 AND test_data.voltage > 9 AND test_data.voltage < 11) OR   
  ( test_data.step = 2 AND test_data.temperature > 50 AND test_data.temperature < 60 AND test_data.voltage > 14 AND test_data.voltage < 16 );

我的目标是不具有静态查询,而是使查询本身基于条件表中的动态数据集构建,该数据集可以包含任意数量的包含条件的行。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

SELECT DISTINCT
    serial_number,
    temperature,
    voltage
FROM (   
    SELECT
        *,
        CASE 
            WHEN column_name = ‘temperature’ AND A.temperature >= B.lower AND A.temperature <= B.upper THEN ‘passed_temp_criteria’ 
        ELSE ‘failed’
        END AS temp_check,
        CASE
            WHEN column_name = ‘voltage’ AND A.voltage >= B.lower AND A.voltage <= B.upper THEN ‘passed_volt_criteria’ 
            ELSE ‘failed’ 
        END AS volt_check 
    FROM test_data A
    JOIN criteria B
    ON A.step = B.step
) C 
WHERE temp_check != ‘failed’ AND volt_check != ‘failed’

答案 1 :(得分:0)

汇总两次字符串以生成WHERE条件文本。

select STRING_AGG(stepexpr, ' or ')
from (
   select '(step = ' || step || ' and ' || STRING_AGG(column_name || ' > ' || lower || ' and ' || column_name || ' < ' || upper, ' and ') || ')' stepexpr
   from criteria
   group by step
) t;

结果

(step = 2 and temperature > 50 and temperature < 60 and voltage > 14 and voltage < 16) or (step = 1 and temperature > 20 and temperature < 30 and voltage > 9 and voltage < 11)