我有一个以下形式的SQL表:
TimeStamp OeprationID MachineID MachineOSVersion
xxx 1 MAC1 Vista
xxx 2 MAC2 Linux
xxx 3 MAC2 Linux
xxx 4 MAC3 MACOS
订阅信息可用:
SubscriptionID MachineID
SUB1 MAC1
SUB2 MAC2
SUB3 MAC3
SUB3 MAC3
SUB3 MAC3
我想使用LEFT JOIN来实现一个表,它给出了这样的结果:
MachineID MachineOSVersion Subscription
MAC1 Vista SUB1
MAC2 Linux SUB2
MAC3 MACOS SUB3
操作表包含一个MachineOSVersion,我想将其与机器和订阅详细信息一起显示。涉及的领域较多,但仅限于样本。
编辑: 原始问题的变化:订阅表有多个MachineID,对于每个机器MachineID,我想在Operations表中查找并找出可用的“最新”MachineOSVersion。由于机器OS可以升级,因此可能会从较旧的日期更改为较晚的日期。因此,必须挑选最新的。
我在使用左连接时遇到的问题是我看到生成了多个重复项。可能是因为操作表中有很多机器机器ID?
答案 0 :(得分:1)
我只会使用常规INNER JOIN
和GROUP
结果来获取所需的输出,并在INNER JOIN
上添加一个子查询,以确保您获得最新的MachineOSVersion
子查询获得最大MachineOSVersion
的每台机器的最后OperationId
,但如果需要,您可以使用另一个字段,可能是时间戳。
MS SQL Server 2012架构设置:
CREATE TABLE MachineTable
(
[TimeStamp] VARCHAR(3) ,
[OperationID] INT ,
[MachineID] VARCHAR(4) ,
[MachineOSVersion] VARCHAR(6)
);
INSERT INTO MachineTable
( [TimeStamp], [OperationID], [MachineID], [MachineOSVersion] )
VALUES ( 'xxx', 1, 'MAC1', 'Vista' ),
( 'xxx', 2, 'MAC2', 'Linux1' ),
( 'xxx', 3, 'MAC2', 'Linux2' ),
( 'xxx', 4, 'MAC3', 'MACOS' );
CREATE TABLE SubscriptionsTable
(
[SubscriptionID] VARCHAR(4) ,
[MachineID] VARCHAR(4)
);
INSERT INTO SubscriptionsTable
( [SubscriptionID], [MachineID] )
VALUES ( 'SUB1', 'MAC1' ),
( 'SUB2', 'MAC2' ),
( 'SUB3', 'MAC3' ),
( 'SUB3', 'MAC3' ),
( 'SUB3', 'MAC3' );
查询1 :
SELECT st.MachineId ,
st.SubscriptionId ,
mt.MachineOSVersion,
mt.OperationID
FROM SubscriptionsTable st
INNER JOIN MachineTable mt ON mt.MachineId = st.MachineId
AND mt.OperationID = (SELECT MAX(mt2.OperationID)
FROM MachineTable mt2
WHERE mt2.MachineId = mt.MachineId)
GROUP BY st.MachineId ,
st.SubscriptionId ,
mt.MachineOSVersion,
mt.OperationID
<强> Results 强>:
| MACHINEID | SUBSCRIPTIONID | MACHINEOSVERSION | OPERATIONID |
|-----------|----------------|------------------|-------------|
| MAC1 | SUB1 | Vista | 1 |
| MAC2 | SUB2 | Linux2 | 3 |
| MAC3 | SUB3 | MACOS | 4 |
答案 1 :(得分:0)
答案 2 :(得分:0)
SELECT MachineID, MachineOSVersion, SubscriptionID AS Subscription
FROM Table1name AS op
LEFT OUTER JOIN Table2name AS sub
ON sub.MachineID = op.MachineID
ORDER BY MachineID
使用LEFT OUTER JOIN非常重要,因为这比LEFT JOIN&#39;更符合要求。 (它更有可能跨不同类型的数据库工作)
答案 3 :(得分:0)
试试这个。从distinct rows
表中找到Subscription
,然后在Left join
中找到与其他表格对应的结果。
SELECT SubscriptionID,
MachineOSVersion,
A.MachineID
FROM (SELECT DISTINCT SubscriptionID,
MachineID
FROM Subscription) A
LEFT JOIN operation B
ON A.MachineID = B.MachineID
更新:
从Operation表中获取最新一行。使用Window function
从Operation
表中获取最新行。
WITH cte
AS (SELECT Row_number()OVER (partition BY [TimeStamp], [MachineID] ORDER BY [OeprationID] DESC) rn,
*
FROM operation)
SELECT SubscriptionID,
MachineOSVersion,
A.MachineID
FROM (SELECT [TimeStamp],[OeprationID],[MachineID],[MachineOSVersion]
FROM cte
WHERE rn = 1) A
RIGHT JOIN (SELECT DISTINCT SubscriptionID,MachineID
FROM SubscriptionsTable) B
ON A.MachineID = B.MachineID
答案 4 :(得分:0)
只是另一种始终获得最新价值的解决方案
SELECT
st.MachineID,
st.SubscriptionID
(SELECT TOP 1 mt.MachineOSVersion FROM MachineTable mt
WHERE mt.MachineID = st.MachineID ORDER BY mt.TimeStamp DESC)
FROM
(SELECT distinct(sti.MachineID),sti.SubscriptionID FROM SubscriptionsTable sti) st;
select(下面的查询)中的子查询将始终根据时间戳获取最新版本。这可能是一个更好的方法,然后继续操作id,因为operationid可能并不总是给出正确的顺序(例如,某些分布式数据库不保证主键始终完全按照正确的顺序)
(SELECT TOP 1 mt.MachineOSVersion FROM MachineTable mt
WHERE mt.MachineID = st.MachineID ORDER BY mt.TimeStamp DESC)
-- Gets the latest machine os version of a system, done by
-- selecting the last entry based on the timestamp
在FROM表中,我们选择不同的机器ID以消除任何重复的机器ID。
(SELECT distinct(sti.MachineID),sti.SubscriptionID FROM SubscriptionsTable sti) st;
示例sqlfiddle。
小提琴的DDL: CREATE TABLE MachineTable ( [TimeStamp] INT, [OperationID] INT, [MachineID] VARCHAR(10), [MachineOSVersion] VARCHAR(10) );
INSERT INTO MachineTable
( [TimeStamp], [OperationID], [MachineID], [MachineOSVersion] )
VALUES ( 1415616586, 1, 'MAC1', 'Vista' ),
( 1416480586, 2, 'MAC2', 'Linux v1' ),
( 1416912586, 3, 'MAC2', 'Linux v2' ),
( 1416998987, 4, 'MAC3', 'MACOS' );
CREATE TABLE SubscriptionsTable
(
[SubscriptionID] VARCHAR(4) ,
[MachineID] VARCHAR(4)
);
INSERT INTO SubscriptionsTable
( [SubscriptionID], [MachineID] )
VALUES ( 'SUB1', 'MAC1' ),
( 'SUB2', 'MAC2' ),
( 'SUB3', 'MAC3' ),
( 'SUB3', 'MAC3' ),
( 'SUB3', 'MAC3' );
小提琴的SQL查询:
SELECT
st.MachineID,
st.SubscriptionID,
(SELECT TOP 1 mt.MachineOSVersion FROM MachineTable mt WHERE mt.MachineID = st.MachineID ORDER BY mt.TimeStamp DESC)
FROM
(SELECT distinct(sti.MachineID),sti.SubscriptionID FROM SubscriptionsTable sti) st;
注意:DDL基于Tanner的DDL。