为SELECT MIN()语句选择其他列

时间:2013-11-27 15:04:04

标签: sql-server sql-server-2005 select group-by

我有这个当前选择:

  SELECT MIN(CONVERT(DateTime,SUBSTRING(NameAndDate,14,8))),
         SUBSTRING(NameAndDate,1,12)
    FROM MyData
   WHERE pName IN (SELECT SUBSTRING(NameAndDate,1,12)
                     FROM MyData
                 GROUP BY SUBSTRING(NameAndDate,1,12)
                   HAVING COUNT(*) > 1)
GROUP BY SUBSTRING(NameAndDate,1,12)

其中SUBSTRING(NameAndDate,1,60)是该人的ID名称,SUBSTRING(NameAndDate,61,8)是他们进入的日期。

很多时候,这些数据会在表格中多次显示,这就是我想选择MIN日期的原因。

问题在于我需要添加表格(ID)中的另一列,但我不想通过它进行分组,因为它会在Person的ID中添加重复项。 / p>

有没有办法可以做到以下几点:

  SELECT ID,
         MIN(CONVERT(DateTime,SUBSTRING(NameAndDate,14,8))),
         SUBSTRING(NameAndDate,1,12)
    FROM MyData
   WHERE pName IN (SELECT SUBSTRING(NameAndDate,1,12)
                     FROM MyData
                 GROUP BY SUBSTRING(NameAndDate,1,12)
                   HAVING COUNT(*) > 1)
GROUP BY SUBSTRING(NameAndDate,1,12)

编辑:

一个人可能会多次出现:

 ID | NameAndDate
----+-----------------------
  1 | J60047238486 08162013
  2 | J60047238486 08182013
  3 | J60047238486 08242013
  4 | J60047238486 09032013
  5 | J60047238486 10102013
  6 | C40049872351 05302013
  7 | C40049872351 07212013
  8 | C40049872351 07252013

我目前的选择拉动:

         Name | Date
--------------+---------------------
 J60047238486 | 08/16/2013 00:00:00
 C40049872351 | 05/30/2013 00:00:00

但我想为这些特定行添加ID列:

 ID |     Name     | Date
----+--------------+---------------------
  1 | J60047238486 | 08/16/2013 00:00:00
  6 | C40049872351 | 05/30/2013 00:00:00

3 个答案:

答案 0 :(得分:1)

你可以这样做,但它不是很漂亮。您必须运行原始查询以获取每个名称的最小日期,然后将其连接回MyData表。由于您存储数据的方式,它特别难看。将MMDDYYYY字符串转换为数据非常有趣。

SQL Fiddle

select
MyData.[ID],
t1.theName,
t1.theDate
from
Mydata
inner join
(
select
SUBSTRING(NameAndDate,1,12) as theName,
min (
convert(datetime,
right (SUBSTRING(NameAndDate,14,8),4) + '-' + 
left (SUBSTRING(NameAndDate,14,8),2) +  '-' + 
SUBSTRING((SUBSTRING(NameAndDate,14,8)),3,2)
))as theDate
from
mydata

where
SUBSTRING(NameAndDate,1,12) in
(SELECT SUBSTRING(NameAndDate,1,12)
                     FROM MyData
                 GROUP BY SUBSTRING(NameAndDate,1,12)
                   HAVING COUNT(*) > 1)

group by
SUBSTRING(NameAndDate,1,12) ) t1
ON SUBSTRING(mydata.NameAndDate,1,12) = t1.theName
AND (convert(datetime,
right (SUBSTRING(NameAndDate,14,8),4) + '-' + 
left (SUBSTRING(NameAndDate,14,8),2) +  '-' + 
SUBSTRING((SUBSTRING(NameAndDate,14,8)),3,2))) = t1.theDate

答案 1 :(得分:1)

试试这个

SELECT * FROM (
SELECT id, 
 CONVERT(DateTime,right (SUBSTRING(NameAndDate,14,8),4) 
                            + SUBSTRING(NameAndDate,14,4)) D,

SUBSTRING(NameAndDate,1,12) N,

COUNT(*) OVER (PARTITION BY SUBSTRING(NameAndDate,1,12)) Cnt,

ROW_NUMBER() OVER (PARTITION BY SUBSTRING(NameAndDate,1,12) 
                   ORDER By SUBSTRING(NameAndDate,14,8)) rn
FROM
mydata
) v WHERE CNT > 1 and rn = 1;

SQL DEMO HERE

答案 2 :(得分:0)

with cte as (
    -- first cte - parsing data
    select
        ID,
        left(NameAndDate, 12) as Name,
        convert(date,
            right(NameAndDate, 4) + 
            substring(NameAndDate, 14, 2) +
            substring(NameAndDate, 16, 2),
        112) as Date
    from Table1
), cte2 as (
    -- second cte - create row_number  
    select
        ID, Name, Date,
        row_number() over(partition by Name order by Date) as rn
    from cte
)
select
    ID, Name, Date
from cte2
where rn = 1

<强> sql fiddle demo