我在SQL上非常糟糕,并且在使用两个表的UNIQUE连接时遇到了一些麻烦。 SQL结构有点糟糕,但我没有设计它。
我有两张桌子:
用户
uid,ufn,uln,ue
用户ID = uid。
和
交易
uid,unit,address,start_date
基本上在事务表中,每个uid有多个条目。我要做的是根据 ONLY 最新的start_date选择users.ufn, users.uln, users.ue, transactions.unit, transactions.address
。意思是每个uid只会得到 ONE 结果。目前,我正在transactions
表中获得所有 uid条目的退货。
我尝试过使用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
我尝试过的其他东西。
任何关于正确方向的提示都将非常感激。谢谢!
答案 0 :(得分: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
答案 1 :(得分: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);
答案 2 :(得分: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与用户相关,那么您将获得两者
答案 3 :(得分: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
P.S。:您绝对应该考虑在transactions
表中添加主键。这样可以在t1
和t2
之间建立更好的连接子句。此外,它还可以防止在同一用户发生多个start_date
时可能发生的重复。
P.P.S。:不会在last_transaction_start_date
表中添加user
列更明智吗?
答案 4 :(得分:-1)
我不确定这是否与MySQL中的语法完全相同(很可能是),但是这里是你如何在SQL服务器中完成它。
使用rank()函数确定最新日期。
SELECT x。*,y。* 来自用户x 加入 (SELECT *,RANK()Over(按UID顺序分配Start_Date DESC)作为Rank_ FROM Transactions)为y ON x.uid = y.uid和y.rank_ = 1
希望这会有所帮助。
干杯!