SQL面试测试

时间:2017-03-26 11:04:03

标签: sql postgresql

作为面试的一部分,我得到了以下问题,我很想知道最佳解决方案。该问题已经过编辑,因此无法识别。

问题

表'交易'具有以下结构:

create table transactions (
        sent_from varchar not null,
        receiver varchar not null,
        date date not null,
        usd_value integer not null);

编写一个查询,返回最多3笔交易中至少收到1024美元的收件人列表。 该帐户可以有超过3个转换器,只要3个或更少的交易usd_value总计至少1024美元。该表应按名称排序(按升序排列)。

示例,给定数据:

sent_from   | receiver     | date       | usd_value 
------------+--------------+------------+--------
Jonas       | Willhelm     | 2000-01-01 | 200
Jonas       | Timpson      | 2002-09-27 | 1024
Jonas       | Bjorn        | 2001-03-16 | 512
Willhelm    | Bjorn        | 2010-12-17 | 100
Willhelm    | Bjorn        | 2004-03-22 | 10
Brown       | Bjorn        | 2013_03_20 | 500
Bjorn       | Willhelm     | 2007-06-02 | 400
Bjorn       | Willhelm     | 2001-03-16 | 400
Bjorn       | Willhelm     | 2001-03-16 | 200

查询应返回以下行集:

  account_name
 --------------
  Bjorn
  Taylor

Bjorn账户上市是因为它在以下三笔交易中收到了1112美元512美元+ 100美元+ 500美元= 1112美元。 Timpson账户仅在一次转账中就收到了1024美元。 Willhelm账户在四笔交易中收到1200美元,但未列出,因为该账户的三笔交易总额至少为1024美元。

我的解决方案:

WITH ordered_transactions AS (
  SELECT
    receiver, usd_value,
    ROW_NUMBER()
    OVER (PARTITION BY
      receiver
      ORDER BY usd_value DESC) AS Row_ID
  FROM public.transactions
)

SELECT receiver FROM
  (SELECT receiver, sum(usd_value) as smount
  FROM ordered_transactions
  WHERE Row_ID < 4
  GROUP BY receiver) AS reduced
WHERE reduced.smount >= 1024
ORDER BY reduced.receiver ASC;

设置数据(postgreSQL):

- 我试图在www.sqlfiddle.com - http://sqlfiddle.com/#!15/13fc3/3

中进行设置
create table transactions (
    sent_from    VARCHAR NOT NULL,
    receiver VARCHAR NOT NULL,
    date      DATE    NOT NULL,
    usd_value    INTEGER NOT NULL);


insert into transactions VALUES ('Jonas', 'Willhelm', to_date('2000-01-01', 'YYYY-MM-DD'), 200 );
insert into transactions VALUES ('Jonas', 'Taylor', to_date('2002-09-27', 'YYYY-MM-DD'), 1024 );
insert into transactions VALUES ('Jonas', 'Bjorn', to_date('2001-03-16', 'YYYY-MM-DD'), 512 );
insert into transactions VALUES ('Willhelm', 'Bjorn', to_date('2010-12-17', 'YYYY-MM-DD'), 100 );
insert into transactions VALUES ('Willhelm', 'Bjorn', to_date('2004-03-22', 'YYYY-MM-DD'), 10 );
insert into transactions VALUES ('Brown', 'Bjorn', to_date('2013-03-20', 'YYYY-MM-DD'), 500 );
insert into transactions VALUES ('Bjorn', 'Willhelm', to_date('2007-06-02', 'YYYY-MM-DD'), 400 );
insert into transactions VALUES ('Bjorn', 'Willhelm', to_date('2001-03-16', 'YYYY-MM-DD'), 400 );
insert into transactions VALUES ('Bjorn', 'Willhelm', to_date('2001-03-16', 'YYYY-MM-DD'), 200 );

关于我应该如何处理这个问题的任何提示都非常感谢。

6 个答案:

答案 0 :(得分:3)

您的解决方案似乎很好,但您可以使用having子句简化查询:

SELECT receiver
FROM ordered_transactions
WHERE Row_ID < 4
GROUP BY receiver
HAVING SUM(usd_value) >= 1024
ORDER BY receiver ASC;

答案 1 :(得分:1)

我想我会把它写成:

WITH t AS (
      SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY receiver ORDER BY usd_value DESC) as seqnum
      FROM public.transactions t
      WHERE usd_value >= 0
     )
SELECT receiver
FROM t
WHERE seqnum <= 3
GROUP BY receiver 
HAVING sum(usd_value) >= 1024
ORDER BY receiver;

问题尚不清楚amount字段中是否存在负数。如果可能,那么始终采用第一个值将不准确(通常)。然而,对于所提供的数据而言,这将是准确的。

我可以看到别人使用子查询而不是HAVING。但这应该对性能没有影响(在Postgres中)并且相当轻微。

答案 2 :(得分:0)

SELECT processed_table.receiver AS account_name, SUM(processed_table.usd_value) AS received_money
FROM

    (
         SELECT temp_table.receiver, temp_table.sent_from, temp_table.usd_value,
         row_number() OVER(PARTITION BY temp_table.receiver ORDER BY 
         temp_table.usd_value 
         DESC) AS row_number 
         FROM transactions AS temp_table
    ) AS processed_table

WHERE processed_table.row_number <=  3
GROUP BY(processed_table.receiver)
HAVING SUM(processed_table.usd_value) >= 1024
ORDER BY processed_table.receiver
;

答案 3 :(得分:0)

另一种方法: SELECT接收者,SUM(usd_value)作为总和,COUNT(receiver)作为交易中的总和,其中 GROUP BY接收者的HAVING计数<= 3 AND和> = 1024

答案 4 :(得分:0)

这是简单的查询

ffmpeg  -framerate 30 -f x11grab -i :1 -f pulse -i default -c:v libx264 -s 1920x1080 -r 60 -b:v 5000k  -crf 10 -vf format=yuv420p -c:a aac -b:a 128k -f flv rtmp://a.rtmp.youtube.com/live2/stream_key

答案 5 :(得分:0)

WITH ordered_transactions AS (
  SELECT
    receiver, usd_value, ROW_NUMBER() OVER (PARTITION BY receiver ORDER BY usd_value DESC) AS Row_ID
  FROM transactions
)
  SELECT receiver
  FROM ordered_transactions
  WHERE Row_ID < 4
  Group by receiver
   having sum(usd_value)>= 1024
  order by receiver;