15天的Sql来自hackerrank

时间:2017-09-15 09:09:47

标签: mysql sql-server

我无法理解在代码中使用此行可以有人请您解释一下这个问题或者给出一些不同的方法来解决这个问题

链接到问题:https://www.hackerrank.com/challenges/15-days-of-learning-sql

代码:

int count = 0;
for (  auto& t : v ) 
    if (t.countable()) count++;

无法理解为什么他们从代码的这一部分使用了这一行:

select 
    submission_date ,    
    (    SELECT COUNT(distinct hacker_id)  
         FROM Submissions s2  
         WHERE s2.submission_date = s1.submission_date 
               AND (  SELECT COUNT(distinct s3.submission_date) 
                         FROM      Submissions s3 
                         WHERE 
                           s3.hacker_id = s2.hacker_id 
                           AND s3.submission_date < s1.submission_date
                   ) = dateDIFF(s1.submission_date , '2016-03-01')) 
    , (   select hacker_id  
          from submissions s2 
          where s2.submission_date = s1.submission_date 
          group by hacker_id 
         order by count(submission_id) desc , hacker_id limit 1
       ) as shit
    ,  (   select name 
           from hackers where hacker_id = shit
       )
FROM  
(    select distinct submission_date 
     from submissions) s1
group by submission_date

2 个答案:

答案 0 :(得分:0)

CREATE TABLE #max_submissions (
    submission_date date,
    hacker_id integer,
    submission_count integer,
    ordering_row integer
)

insert into #max_submissions 
select 
    submission_date, 
    hacker_id, 
    submission_count, 
    row_number() over(partition by submission_date order by submission_count desc, hacker_id) as ordering_row
from (
    select submission_date, 
            hacker_id,
            count(hacker_id) as submission_count
    from submissions
    group by submission_date, hacker_id
) tbl_submission_count 

CREATE TABLE #hacker_counts (
    submission_date date,
    hacker_count integer
)

insert into #hacker_counts
select tbl.submission_date, 
        COUNT(distinct tbl.hacker_id) as cc 
from (
    select *,
            (case when (
                            (select count(*) 
                                from (select distinct * 
                                        from (select s1.hacker_id, 
                                                    s1.submission_date 
                                                from Submissions s1 
                                                where s1.hacker_id = s.hacker_id and
                                                (s1.submission_date >= '2016-03-01' and 
                                                s1.submission_date <= s.submission_date)) t1 
                                    ) t2 
                            ) >= (DATEDIFF(day, '2016-03-01', s.submission_date) + 1) )
                    then 1
                    else 0
            end) as logic
    from Submissions s
) tbl
where tbl.logic = 1
group by tbl.submission_date



select max_submissions.submission_date, 
    hacker_counts.hacker_count, 
    max_submissions.hacker_id, 
    h.name 
from #max_submissions max_submissions
inner join hackers h on max_submissions.hacker_id = h.hacker_id
left join #hacker_counts hacker_counts on max_submissions.submission_date = hacker_counts.submission_date
where max_submissions.ordering_row = 1
order by max_submissions.submission_date

drop table #max_submissions
drop table #hacker_counts

答案 1 :(得分:0)

理解这一行

(  SELECT COUNT(distinct s3.submission_date) 
          FROM      Submissions s3 
          WHERE 
          s3.hacker_id = s2.hacker_id 
          AND s3.submission_date < s1.submission_date)
                  = dateDIFF(s1.submission_date , '2016-03-01')

先了解左手边:

(SELECT COUNT(distinct s3.submission_date) FROM Submissions s3 WHERE s3.hacker_id = s2.hacker_id AND s3.submission_date < s1.submission_date)

这一行计算每个hacker_id直到当前日期的唯一提交日期, 因此,如果一行的日期是 2016-03-05,它将计算一个hacker_id 直到该日期的唯一提交(请注意,它会将单个黑客在一天内的多次提交计算为仅计算 1 个)

换句话说,这需要一个hacker_id并开始检查从第一天到今天的每一天是否有这个hacker_id提交,它会在每个提交日期执行此操作

然后理解右手边: dateDIFF(s1.submission_date , '2016-03-01') 这将采用当前日期 2016-03-05 与第一天 2016-03-01 的差值,

现在理解整个声明:

所以如果黑客从2016-03-052016-03-01每天至少提交一次提交,那么上面代码的两边就相等了, 即从 5 日到 1 日的日期差将是 5(右侧),对于每天至少提交一次从 1 日到 5 日提交的黑客来说,不同的提交日期也将是 5(左侧)