首页 > 解决方案 > SQL查询多次返回结果 [已解决]

问题描述

我对 SQL 很陌生,正在尝试在 SQL 中加入一些表。我正在使用SQLite3并且Pandas具有以下表结构:

    User
      |
Measurement - Environment - meas_device - Device
      |                          | 
    Data                 Unit_of_Measurement

为什么我多次 (4x) 得到以下 SQL 查询的结果?

query = """
SELECT User.name, Measurement.id, Data.set_id, Data.subset_id, Data.data 
FROM Measurement
JOIN Data ON Measurement.id = Data.measurement_id
JOIN User ON Measurement.user_id = user.id
JOIN Environment ON Measurement.Environment_id = Environment.id
JOIN meas_device ON Environment.meas_dev_ids = meas_device.id
JOIN Device ON meas_device.device_id = Device.id
JOIN Unit_of_Measurement ON meas_device.Unit_id = Unit_of_Measurement.id
WHERE User.name = 'nicola'
"""

pd.read_sql_query(query, conn)

我的猜测是我在加入时做错了什么,但我看不出是什么。我希望能够在某个地方保存一个适用于每个可能查询的 JOIN 语句,这就是为什么连接的表比这个查询所需的多。

更新 我认为问题出在环境表中。每当我加入此表时,结果都会成倍增加。由于 Environment 是 meas_devices 的集合,因此有多个具有相同 Environment id 的条目。(我可以将具有相应 meas_device_id 的 Environment 表保存为列表,但是我看不到将 Environment 表与 meas_device 表链接的可能性。)

id | meas_device_id
1  |      1
1  |      2
1  |      5
2  |      3
2  |      4

到目前为止,我创建了表,pandas DataFrame.to_sql()因此 id 没有被标记为主键或类似的东西。这可能是我的问题的原因吗

更新 2 我发现了问题。我不认为这实际上对将来的某人有帮助。但为了完整起见,这里解释一下。这实际上不是如何链接表格的问题,但我忽略了一个关键链接。因为环境具有多个具有相同值的索引,所以它创建了“开放端”,导致结果相乘。我需要在 Environment.subset_id 和 Data.subset_id 之间添加交叉检查。以下查询工作正常:

query = f""" SELECT {SELECT}
          FROM Data
          JOIN Measurement ON Data.measurement_id = Measurement.id
          JOIN User ON Measurement.user_id = User.id
          JOIN Environment ON Measurement.Environment_id = Environment.id
          JOIN meas_device ON Environment.meas_dev_ids = meas_device.id
          JOIN Device ON meas_device.Device_id = Device.id
          JOIN Unit_of_Measurement ON meas_device.Unit_id = Unit_of_Measurement.id
          WHERE {WHERE} AND Environment.subset_id = Data.subset_id
          """

标签: pythonsqlpandassqlite

解决方案


如果您需要过滤在结果中产生额外行的表(当它们连接时),请不要连接它们,而是将它们包含在 WHERE 子句的子查询中。

例如

SELECT User.name, Measurement.id, Data.set_id, Data.subset_id, Data.data
FROM
    Measurement
    JOIN Data ON Measurement.id = Data.measurement_id
    JOIN User ON Measurement.user_id = user.id
WHERE
    Measurement.Environment_id IN (
        SELECT Environment.id
        FROM
            Environment
            JOIN meas_device ON Environment.meas_dev_ids = meas_device.id
            JOIN Device ON meas_device.device_id = Device.id
            JOIN Unit_of_Measurement ON meas_device.Unit_id = Unit_of_Measurement.id
        WHERE Device.name = 'xy'
    )

在此子查询中,您可以连接许多表而无需生成额外的记录。

如果这不是一个选项,因为您还想从其他表中选择条目,您可以简单地将 DISTINCT 添加到您的原始查询中。

SELECT DISTINCT
    User.name, Measurement.id, Data.set_id, Data.subset_id, Data.data 
FROM
   Measurement
   JOIN Data ON Measurement.id = Data.measurement_id
   JOIN User ON Measurement.user_id = user.id
   JOIN Environment ON Measurement.Environment_id = Environment.id
   JOIN meas_device ON Environment.meas_dev_ids = meas_device.id
   JOIN Device ON meas_device.device_id = Device.id
   JOIN Unit_of_Measurement ON meas_device.Unit_id = Unit_of_Measurement.id
WHERE
   User.name = 'nicola'

推荐阅读