2017-09-22 66 views
1

我有以下表snapshotsSQL:如何在sql中查找每個組的最小值?

domain  year month day 
---   --- --- --- 
google  2007 04 15 
google  2005 08 31 
google  2005 12 01 
facebook 2006 04 15 
facebook 2006 02 25 
facebook 2008 01 01 

我想要檢索的每個域的第一(最早)的日期。

所以輸出應該是:

google 2005 08 31 
facebook 2006 02 25 

我曾嘗試以下查詢,但它檢索每個列的最小值:

select domain, min(year), min(month), min(day) from snapshots group by domain 
+0

你使用MySQL或SQL Server? –

+0

您需要將它們作爲串聯後的日期並應用MIN函數。 – SriniV

+0

@GiorgosBetsos MySQL – SaadH

回答

2

如前所述,你應該使用串聯創建單日期然後選擇最低值。

select domain, MIN(CAST(CONCAT(`year`, '-'`,month`,'-',`day`) AS DATE)) from snapshots group by domain 

還沒有測試過,但這應該給你一個想法。

+0

謝謝,它的工作:) – SaadH

1

您可以連接從日期字段中的值,施展他們的日期,然後選擇分鐘日期(我期待值是在這種情況下,VARCHAR):

SELECT domain, 
MIN(CAST(CONCAT(year,'-',month,'-',day) AS date)) 
FROM snapshots 
GROUP BY domain; 
+0

謝謝!連接確實簡化了它。 – SaadH

1

在MySQL: SELECT domain, FROM_UNIXTIME(UNIX_TIMESTAMP(MIN(CONCAT(year,'-',month,'-',day))), '%Y') as y, FROM_UNIXTIME(UNIX_TIMESTAMP(MIN(CONCAT(year,'-',month,'-',day))), '%m') as m, FROM_UNIXTIME(UNIX_TIMESTAMP(MIN(CONCAT(year,'-',month,'-',day))), '%d') as d FROM snapshots GROUP BY domain ;

0

可能有更簡單的解決方案,但是您可以從年份,月份和日期三欄中創建一個新的日期類型列。然後拿到分鐘日期如下:

SELECT DISTINCT s.domain, s.year, s.month, s.day 
FROM 
(
    SELECT domain, year,month,day, 
     STR_TO_DATE(CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00')) ,'%Y-%m-%d') AS FullDate 
    FROM snapshots 
) AS s 
INNER JOIN 
(
    SELECT domain, MIN(Fulldate) MinDate 
    FROM 
    (
    SELECT domain, year,month,day, 
     STR_TO_DATE(CONCAT(`year`,'-',LPAD(`month`,2,'00'),'-',LPAD(`day`,2,'00')) ,'%Y-%m-%d') AS FullDate 
    FROM snapshots 
) AS t 
    GROUP BY domain 
) AS t ON t.MinDate = s.FullDate 
     AND t.Domain = s.Domain; 

demo

這會給你你想要的確切結果:

| domain | year | month | day | MinDate | 
|----------|------|-------|-----|------------| 
| google | 2005 |  8 | 31 | 2005-08-31 | 
| facebook | 2006 |  2 | 25 | 2006-02-25 | 
0

你可以試試這個,請讓我知道,如果它解決你的問題沒有連接?如有必要,可以使用子查詢更健壯。

CREATE TABLE domainDate(domain CHAR(25), `year` INT, `month` INT, `day` INT); 

INSERT INTO domainDate VALUES 
    ('google', 2007, 04, 15), 
    ('google', 2005, 08, 31), 
    ('google', 2005, 12, 01), 
    ('facebook', 2006, 04, 15), 
    ('facebook', 2006, 02, 25), 
    ('facebook', 2008, 01, 01); 

SET @VDomain := ''; 
SELECT domain, `year`, `month`, `day` FROM domainDate HAVING @VDomain != @VDomain := domain ORDER BY domain, `year` * 10000 + `month` * 100 + `day`; 

感謝,

詹姆斯

0

您可以嘗試排序函數ROW_NUMBER()

CREATE TABLE domainDate(domain CHAR(25), [year] INT, [month] INT, [day] INT); 

INSERT INTO domainDate VALUES 
    ('google', 2007, 04, 15), 
    ('google', 2005, 08, 31), 
    ('google', 2005, 12, 01), 
    ('facebook', 2006, 04, 15), 
    ('facebook', 2006, 02, 25), 
    ('facebook', 2008, 01, 01); 

SELECT domain 
    ,[year] 
    ,[month] 
    ,[day] 
FROM 
(
    SELECT domain 
     ,[year] 
     ,[month] 
     ,[day] 
     ,ROW_NUMBER() OVER(PARTITION BY domain ORDER BY [year], [month], [day]) AS RN 
    FROM domainDate 
) t 
WHERE RN = 1 
相關問題