1

我在 SQL 方面很糟糕,并且在对两个表进行 UNIQUE 连接时遇到了一些麻烦。SQL 结构有些糟糕,但不是我设计的。

我有两张桌子:

用户

uid, ufn, uln, ue

其中用户 id = uid。

交易

uid、单位、地址、开始日期

基本上在事务表中,每个 uid 有多个条目。我要做的是users.ufn, users.uln, users.ue, transactions.unit, transactions.address基于最新的 start_date 进行选择。这意味着每个 uid我只会得到一个结果。目前,我正在获得表中所有uid 条目的回报。transactions

我试过用 MAX 做一些 JOINS、LEFT JOINS 和一些事情,但基本上都没有成功。

SELECT * FROM users JOIN ( SELECT unit, address, start_date FROM transactions GROUP BY uid) as a ON users.tenant_id = a.tenant_id

是我在其他东西中尝试过的。

任何关于正确方向的提示将不胜感激。谢谢!

4

5 回答 5

7

这会让你接近。问题将是如果 2 个事务对同一用户具有相同的开始日期。但是,如果您没有这种情况,这应该可以正常工作。

select u.ufn,
       u.uln,
       u.ue,
       t.unit,
       t.address
from   users u
inner join (
            select uid, 
                   max(start_date) as newest_start_date
            from transactions
            group by uid) x
on u.uid = x.uid
inner join transactions t
on t.start_Date = x.newest_start_date
and t.uid = u.uid
于 2013-06-27T18:27:19.940 回答
1

您的示例 SQL 具有“tenant_id”但不在您的表示例中?您是每天运行一次还是 10000 次?

试试这个:

SELECT users.ufn, users.uln, users.ue, transactions.unit, transactions.address 
FROM users join transactions on users.uid = transactions.uid
WHERE transactions.UID, transactions.start_date IN
(SELECT UID, MAX(start_date) FROM TRANSACTIONS GROUP BY UID);
于 2013-06-27T18:31:27.300 回答
1

另一种选择是在不等式上使用 ANTI JOIN

select users.ufn,
       users.uln,
       users.ue,
       t.unit,
       t.address
from   users
INNER JOIN transactions t 
ON  t.uid = u.uid
LEFT JOIN transactions t1
ON t.uid = t1.uid
 and t.start_date < t1.start_date

WHERE
      t1.uid is null

因为 t.start_date < t1.start_date并且 t1.uid is null只有没有另一条记录具有更大 start_date 的记录才会被选中

MAX()如果两个或多个事务具有与用户相关的 start_dates 一样,您将同时获得两者

于 2013-06-27T18:33:54.843 回答
0

这个查询可以工作:

SELECT
   u.ufn,
   u.uln,
   u.ue,
   t2.unit,
   t2.address
FROM
    users AS u
INNER JOIN
    (
        SELECT
            uid
        ,   MAX(start_date) AS start_date
        FROM
            transactions
        WHERE
            uid = users.uid
    ) AS t1
INNER JOIN
    transaction AS t2 ON t2.uid = t1.uid AND t2.start_date = t1.start_date

临时表也是一种选择(可能更快,你必须尝试):

CREATE TEMPORARY TABLE
    last_transactions
AS SELECT
    uid
,   MAX(start_date) AS start_date
FROM
    transactions
GROUP BY
    uid
;
SELECT
    u.ufn,
    u.uln,
    u.ue,
    t2.unit,
    t2.address
FROM
    users AS u
INNER JOIN
    last_transactions AS t1 ON t1.uid = u.uid
INNER JOIN
    transaction AS t2 ON t2.uid = t1.uid AND t2.start_date = t1.start_date

PS:您绝对应该考虑向transactions表中添加主键。这将允许在t1和之间建立更好的连接子句t2start_date此外,它还可以防止同一用户发生多个重复时可能发生的重复。

PPS:last_transaction_start_date在表格中添加一列不是user更明智吗?

于 2013-06-27T18:33:06.713 回答
-1

我不确定这是否与 MySQL 中的语法完全相同(很可能会如此),但这是您在 SQL Server 中的操作方式。

使用 rank() 函数确定最晚日期。

SELECT x.* , y.* FROM users as x JOIN (SELECT *, RANK() Over (Partition By UID Order By Start_Date DESC) as Rank_ FROM Transactions) as y ON x.uid = y.uid and y.rank_ = 1

希望这可以帮助。

干杯!

于 2013-06-27T18:33:42.310 回答