2017-11-17 114 views
1

根据我的同事,我们正在使用IBM DB2SQL如何让sql返回一行而不是每个不同ID的多个?

真的很难试图让我的sql每个ID返回一行。在工作中被问到,但没有女孩在这里与SQL很好...我可以做一些SQL,但没有SQL专家。

为了更好地解释它,我设置了以下

的例子下面是表和它的数据

ID DATE  CODE PERCENT 
01 2016-08-21 1111 52 
01 2016-09-06 1111 60 
01 2016-10-06 1112 38 
02 2016-05-01 6666 50 
02 2016-10-01 1111 50 

我想每ID每一个返回的记录与最早的日期。 所以我写下面的SQL

SELECT ID, MIN(DATE) 
FROM TABLE 
WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
AND CODE = 1111 
GROUP BY ID 

工作正常。我会得到

01 2016-08-21 
02 2016-10-01 

我很快意识到我也需要PERCENT专栏。

SELECT ID, MIN(DATE), PERCENT 
FROM TABLE 
WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
AND CODE = 1111 
GROUP BY ID, PERCENT 

,但现在,我得到ID 01这是不对的多行...

01 2016-08-21 1111 52 
01 2016-09-06 1111 60 
02 2016-10-01 1111 50 

有人可以帮我解决这个SQL或我指向正确的方向,让我每个ID可以有一行如下?

01 2016-08-21 1111 52 
02 2016-10-01 1111 50 
+0

这是在MS SQL Server中吗? – Sarhang

+1

哪个dbms ??????????? SQL只是一个语言年龄。实现不同于一个dbms到另一个。 – Eric

+0

Alison,知道您使用的数据库类型(例如MySQL Oracle,Postgres,SQL Server ...)非常重要,因为解决方案将取决于数据库支持的内容。 “SQL”本身不够详细。 –

回答

0
SELECT 
    Earliest.ID, 
    Earliest.Date, 
    TABLE.PERCENT 
FROM (
    SELECT 
     ID, 
     MIN(DATE) 
    FROM 
     TABLE 
    WHERE 
     DATE BETWEEN '2016-01-01' AND '2017-11-01' 
     AND CODE = 1111 
    GROUP BY ID 
) AS Earliest 
INNER JOIN TABLE ON Earliest.ID = Table.ID 

要解释为什么您调整查询返回多个记录:百分比列有不同的数据,所以当你通过它组,这将增加一个新的记录上,每一个变化。

在这个答案中,您通过加入到汇总结果中,从基础表中获得百分比。

1

GROUP BY ID将做必要的事情,不需要GROUP BY百分比。如果您使用GROUP BY百分比,则会添加一个新行,因为它具有不同的值。

SELECT ID, MIN(DATE), code, percent 
FROM table 
WHERE DATE BETWEEN '2016-01-01' AND '2017-11-01' 
AND CODE = 1111 
GROUP BY ID; 

希望这会有所帮助。

+0

几乎所有的dbms都会打破。 – Eric

0

如果这是SQL Server,您可以沿着使用TOP 1 WITH TIESORDER BY

SELECT TOP 1 WITH TIES ID, DATE, PERCENT 
FROM TABLE 
WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
AND CODE = 1111 
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DATE ASC) 
0

通过ID通过%的人不群,只是组。在select语句中添加代码。

select id, min(date), code, percent 
from tablename 
where date between '2016-01-01' AND '2017-11-01' 
and code = 1111 
group by id; 
+0

此代码不符合ANSI SQL标准,但可以在Sybase ASE和MySQL上运行。他们接受没有分组的条款。 – ColdCat

0

我假设你正在使用MS SQL Server。您可以使用所谓的CTE(与cluse),以获得分日期,然后将其加入到主表:see the working example on sql fiddle

-- first find the min date for each ID 
with min_date as (
SELECT ID, MIN(DATE) [DATE] 
FROM tbl 
WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
AND CODE = 1111 
GROUP BY ID 
) 

-- join it to the table and get the result 
select t.ID, md.[DATE], t.[PERCENT] 
from tbl t 
inner join min_date as md 
on md.ID = t.ID and md.[DATE] = t.[date] 
1

IF你的数据库支持row_number() over()然后使用该功能是一个很好的方法确定哪些行是“最早的”这样的:

select * 
from (
     select * 
      , row_number() over(partition by ID, CODE order by DATE ASC) as is_oldest 
     from YOURTABLE 
     where DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
     and CODE = 1111 
    ) d 
where is_oldest = 1 

这样做的显著优点是它提供了访问与“最老”而不需要加入相关的整行。

请注意这种方法的灵活性,它可以很容易地扩展,例如,

select * 
from (
     select * 
      , row_number() over(partition by ID, CODE order by date ASC) as is_oldest 
      , row_number() over(partition by ID, CODE order by date DESC) as is_recent 
     from your_table 
     WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
     AND CODE = 1111 
    ) d 
where is_oldest = 1 
or is_recent = 1 

所有的人有做的就是“最近”是从上升到下降的更改顺序。

注:MySQL的前V8不支持“窗口功能,例如ROW_NUMBER,但在V8以后的计划很多其他的数据库都支持这个功能

0

百分比理由击败GROUP BY是因为个百分点。是行之间的不同,你是删除重复与GROUP BY。百分比使该行不同的...你可以代替子查询具有相同的ID和MIN(DATE)

SELECT dT.ID 
     ,dT.DATE 
     ,(SELECT T.PERCENT 
      FROM TABLE T 
     WHERE T.ID = dT.ID AND T.DATE = dT.DATE 
     ) AS Percent 
    FROM (
     SELECT ID, MIN(DATE) AS DATE 
      FROM TABLE 
      WHERE DATE >= '2016-01-01' AND DATE <= '2017-11-01' 
      AND CODE = 1111 
     GROUP BY ID 
     ) AS dT 
表重新获得的行
相关问题