我遇到的问题是尝试从数据库中选择行,其中该行中的2列与特定数据对对齐。换句话说,从id = 1 AND type = 'news'
的数据中选择行。显然,如果它是1个简单对,那将很容易,但问题是我们是根据数百对数据选择行。我觉得好像必须有一些方法来执行此查询而不循环对并单独查询每个。我希望有些SQL堆栈器可以提供指导。
这是一个完整的代码分解:
让我们假设我有以下数据集,其中history_id
是主键。 (为了便于阅读,我简化了有关日期的结构。)
table: history
history_id id type user_id date
1 1 news 1 5/1
2 1 news 1 5/1
3 1 photo 1 5/2
4 3 news 1 5/3
5 4 news 1 5/3
6 1 news 1 5/4
7 2 photo 1 5/4
8 2 photo 1 5/5
如果用户想要根据日期范围从数据库中选择行,我们将获取该数据的子集:
SELECT history_id, id, type, user_id, date
FROM history
WHERE date BETWEEN '5/3' AND '5/5'
返回以下数据集:
history_id id type user_id date
4 3 news 1 5/3
5 4 news 1 5/3
6 1 news 1 5/4
7 2 photo 1 5/4
8 2 photo 1 5/5
现在,使用该数据子集,我需要确定这些条目中有多少代表数据库中每个类型/ ID配对的第一个条目。换句话说,第4行是数据库中第一个时间id: 3
,type: news
出现了吗?所以我使用with()
min()
查询。
在实际代码中,两个列表以编程方式从我们先前查询的结果集生成。 (为了便于阅读,我把它拼写出来。)
WITH previous AS (
SELECT history_id, id, type
FROM history
WHERE id IN (1,2,3,4) AND type IN ('news','photo')
) SELECT min(history_id) as history_id, id, type
FROM previous
GROUP BY id, type
返回以下数据集:
history_id id type user_id date
1 1 news 1 5/1
2 1 news 1 5/1
3 1 photo 1 5/2
4 3 news 1 5/3
5 4 news 1 5/3
6 1 news 1 5/4
7 2 photo 1 5/4
8 2 photo 1 5/5
您会注意到它是整个原始数据集,因为我们在列表中单独匹配id和类型,而不是作为集体对。
我想要的结果就是这个,但我无法弄清楚得到这个结果的SQL:
history_id id type user_id date
1 1 news 1 5/1
4 3 news 1 5/3
5 4 news 1 5/3
7 2 photo 1 5/4
显然,我可以循环遍历每一对并查询数据库以确定其第一个结果,但这似乎是一个低效的解决方案。我认为这个网站上的一位SQL大师可能会传播一些智慧。
如果我不正确地接近这种情况,整个例程的要点是数据库将所有创建和编辑存储在同一个表中。我需要跟踪每个用户的行为,并确定历史记录表中有多少条目是特定日期范围内的编辑或创建。因此,我根据type:id
从日期范围中选择所有user_id
对,然后对于每个配对,我确定用户是否负责数据库中出现的第一条记录。如果是第一个,则“创建”否则“编辑”。
答案 0 :(得分:1)
看不到需要两个查询...... DVK明白了这个想法:
select id, type, MIN(date) as 'min_date'
from history
where date between YOUR_START_DATE and YOUR_END_DATE
group by id, type
答案 1 :(得分:0)
SELECT *
FROM HISTORY,
(SELECT MIN(date) 'min_date', id, type
FROM history
WHERE id IN (1,2,3,4) AND type IN ('news','photo')
-- AND DATE BETWEEN xxx and YYY
GROUP BY id, type) 'min_dates'
WHERE HISTORY.id = min_dates.id
AND HISTORY.type = min_dates.type
AND HISTORY.date = min_dates.min_date
这未经过测试,因为我目前没有数据库访问权限,抱歉
答案 2 :(得分:0)
SELECT
h1.history_id,
h1.id,
h1.type,
h1.user_id,
h1.date
FROM
( select
h2.id,
MIN( h2.history_id ) minHistory
from
history h2
group by
h2.id ) ByType,
history h1
where
ByType.MinHistory = h1.History_ID
无论日期如何,这都将查询整个系统。但是,您可以在内部查询“从历史记录h2”中使用您的WHERE条件来限制日期范围或ID类型或类型说明。
由于内部查询将首先完成,并且显然具有较少的记录,因此将用作加入FULL历史表的主要查询。但由于它仅基于单一的历史记录ID记录,因此只有那个关键记录为“第一”才会返回,因为您希望得到它。