在另一个表中获取最少使用的id

时间:2018-04-16 22:15:44

标签: java sql postgresql

我有两张桌子

帐户表

id INT, username TEXT, password TEXT, proxy_id INT, enabled BOOLEAN

代理表

id INT, proxy_ip TEXT, proxy_port INT

我会有一个循环,一次通过一个帐户。我希望将最少使用的代理分配给table.proxy_id。

例如,如果我们在代理表中有2个代理,在Account表中有5个帐户

1 10.0.0.1  4000
2 10.0.0.1  4001

我们的帐户

1 david    password 2    enabled
2 mark     password 1    enabled
3 jessica  password 1    enabled
4 ashley   password NULL enabled
5 allan    password NULL enabled
6 james    password 2    disabled

我的程序将在Java中循环,遍历所有已启用的帐户,它会将已启用帐户中使用最少的代理分配给该帐户。在上面的例子中,David,Mark和Jessica已经有了一个代理集。因此循环将通过Ashley,并且需要将具有id 2的代理分配给Ashley,因为它是最少使用的。对于Allan代理1或2可以分配,因为它在任何情况下都是最少使用的。詹姆斯应该被忽略,因为他的帐户没有启用。

我希望我的问题清楚。我认为这需要在两个查询中完成?

2 个答案:

答案 0 :(得分:1)

这是一个想法。您需要展开代理ID以获取分配所需的列表。以下是这样做的基本方法,但并不难。为每个id分配额外的100“行”,并从当前计数开始枚举它们。然后订购这些作为作业。

第一部分:

select p.id, count(a.id) as cnt,
       generate_series(1, 100) + count(a.id) as proxy_seqnum
from proxy p left join
     accounts a
     on p.id = a.proxy_id and a.enabled 
group by p.id;

现在,计算整体顺序排序:

select ap.*, row_number() over (order by proxy_seqnum) as seqnum
from (select p.id, count(a.id) as cnt,
             generate_series(1, 100) + count(a.id) as proxy_seqnum
      from proxy p left join
           accounts a
           on p.id = a.proxy_id and a.enabled 
      group by p.id
     ) ap;

我们可以使用此顺序排序来匹配帐户的顺序排序。这将按照“罕见”的顺序给出代理ID,从而产生更平衡的最终结果。

为此,我们需要计算帐户的seqnum:

update accounts a
    set proxy_id = p.id;
    from (select a.*, row_number() over (order by id) as seqnum
          from accounts
         ) aa join
         (select ap.*, row_number() over (order by proxy_seqnum) as seqnum
          from (select p.id, count(a.id) as cnt,
                       generate_series(1, 100) + count(a.id) as proxy_seqnum
                from proxy p left join
                     accounts a
                     on p.id = a.proxy_id and a.enabled 
                group by p.id
               ) ap
           ) p
           on a.seqnum = p.seqnum
    where a.enabled and a.proxy_id is null and
          aa.id = a.id;

答案 1 :(得分:1)

我已经使用Java和SQL。但它使阅读更容易。我测试了它并且它可以工作

<body>
<h2>
    First Paragraph
</h2> 
<button class="expand-button" id="b1" onclick="expand('1')">Read more</button>
<span class="hidden" id="myDIV1"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu magna vitae ipsum dignissim euismod. Curabitur egestas congue elit vitae accumsan. Integer aliquet dictum est, vitae placerat arcu dapibus commodo. Quisque nec libero sed urna tristique mattis sed vel lacus. Praesent ut justo eget elit mattis suscipit. Curabitur ut libero eros. Morbi nec viverra velit. Suspendisse at nulla quis purus luctus laoreet. Nunc euismod ultricies quam vitae mattis. Fusce auctor urna at libero dapibus, sed sollicitudin ex facilisis. Maecenas ultricies nisl sodales lectus ultricies volutpat. Sed pretium turpis vitae dui tincidunt, ac sagittis ante efficitur.</p>
</span>
<h2>
Second Paragraph
</h2>
<button class="expand-button" id="b2" onclick="expand('2')">Read more</button>
<span class="hidden" id="myDIV2">
<p>Nunc porttitor, quam vel consectetur feugiat, ipsum justo accumsan urna, non egestas ante ipsum in tellus. Maecenas pretium, velit dictum ultricies convallis, neque justo aliquet dolor, sed tincidunt massa ipsum at justo. Integer auctor auctor pretium. Ut in lacus ex. Suspendisse id placerat sapien, sed placerat dui. Curabitur eget malesuada arcu. Nam fringilla imperdiet mauris, at malesuada dolor tempor sit amet. Nam feugiat mi vel accumsan tristique. Curabitur imperdiet mollis mi vel consequat. Nam sollicitudin, elit sit amet tincidunt consectetur, sapien elit blandit lorem, at semper ipsum enim eget eros. Cras in ultrices dolor. Maecenas a lacus risus. Duis sed leo id est ultricies rhoncus ac sed ex. Fusce commodo consectetur nunc, sed lacinia sem.
</p>
</span>

</body>

以下是您的SQL方法

  public void setLeastUsedProxy() throws Exception {
    Database db = new Database();

    ArrayList<Integer> allProxies = db.getAllProxies();
    ArrayList<Integer> allAssignedProxies = db.getAssignedProxies();

    ArrayList<Integer> unusedProxies = allProxies;
    unusedProxies.removeAll(allAssignedProxies);

    // assign the unused proxy
    if (unusedProxies.size() > 0) {

    } else {
      Integer leastUsedProxy = db.getLeastUsedProxy();
      System.out.println(leastUsedProxy);
    }

  }