简体   繁体   English

SQL根据另一列中的值从一列中选择值

[英]SQL select value from one column based on values in another column

I have two tables. 我有两张桌子。 One stores "locations": 一个存储“位置”:

TABLE location (
    ID               serial             PRIMARY KEY,
    name             text               NOT NULL,
    description      text               NOT NULL
);

Each location has many rows of "data": 每个位置都有许多行“数据”:

TABLE data(
    ID               smallint           REFERENCES location(ID),
    date             date,               
    rainfall         int                
);

I would like to find all locations that have "data" spanning a given period. 我想找到所有具有给定时间段内“数据”的位置。 I have tried this: 我已经试过了:

SELECT location.ID, location.name FROM location                    
    JOIN data ON data.id = location.id 
    WHERE (SELECT MIN(data.date) FROM data) <= '$start_date' 
           AND 
          (SELECT MAX(data.date) FROM data) >= '$end_date' 
    ORDER BY location.ID;

but it seems to apply the MIN and MAX test to all the data, not to each individual location ie the test needs to be applied to every location, and only return those locations that pass the test. 但似乎将MIN和MAX测试应用于所有数据,而不是应用于每个单独的位置,即测试需要应用于每个位置,并且仅返回通过测试的那些位置。

Any suggestions? 有什么建议么?

Just aggregate by location and then assert the min/max from the HAVING clause: 只需按位置汇总,然后从HAVING子句中声明最小值/最大值即可:

SELECT
    l.ID,
    l.name
FROM location l                 
INNER JOIN data d
    ON d.id = l.id
GROUP BY
    l.ID
HAVING
    MIN(data.date) <= '$start_date' AND
    MAX(data.date) >= '$end_date' 
ORDER BY
    l.ID;

When you say spanning a given period, why not use between like below 当你说跨越一定时期内,为什么不使用between像下面

SELECT location.ID, location.name FROM location location
JOIN data d ON d.id = location.id WHERE d.date between '$start_date' AND '$end_date' ORDER BY location.ID;

Note that both dates are inclusive here 请注意,两个日期都包含在内

you could join a query result for those values and use that in the where condition 您可以将查询结果加入这些值,并在where条件中使用

SELECT location.ID, location.name FROM location                    
JOIN data ON data.id = location.id 
JOIN (
    SELECT MIN(date) AS _min,MAX(date) AS _max,id
    FROM data
    GROUP BY id
) T ON T.id = location.id
WHERE T._min <= '$start_date' AND T._max >= '$end_date' 
ORDER BY location.ID;

just to clarify - I understood you want to get all the data for locations that have data in those time spans (the example implied this is what you wanted) 只是为了澄清-我理解您想获取在那些时间跨度中具有data locations所有data (示例暗示这就是您想要的)

if you want to get all the data that "happened" in the time range this is not the solution for you, you want the between solution offered by @jusermar10 or @Yogs 如果要获取在该时间范围内发生的所有data ,这不是您想要的解决方案,则需要@ jusermar10或@Yogs提供的between解决方案

You could use between clause to get the desired results 您可以使用between子句获得所需的结果

SELECT l.ID, l.name FROM location l                   
    inner JOIN data d ON d.id = l.id 
    WHERE  d.date between '$start_date' and '$end_date' group by l.id

When you say spanning a given period, I suppose you mean output only those locations that have all their data.date between $start_date and $end_date . 当您说跨越给定时间段时,我想您的意思是仅输出所有其data.date$start_date$end_date之间的位置。

In that case this query should work: 在这种情况下,此查询应该起作用:

SELECT location.ID, location.NAME FROM locations, data
WHERE locations.ID=data.ID
GROUP BY locations.ID
HAVING min(data.date) >= '$start_date' and max(data.date) <= $end_date;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM