我是sql的新手,现在已经被困在以下问题上近一天了:
我有两个表,我从中提取值,设备和设备_LOG。我需要显示所有devices_LOG条目,其中devices.status =' 1'我需要它们是唯一的(即我只想看到每个设备的一个devices_LOG条目)。我的代码如下所示:
SELECT DISTINCT
devices_LOG.device_id, MAX(devices_LOG.LogDate) AS LogDate,
manufacturers.name, devices_LOG.LogType, devices_LOG.userName,
devices_LOG.userFullname, devices.invnumber, devices.modelname,
devices.modelnumber
FROM devices_LOG
INNER JOIN
devices ON devices_LOG.device_id = devices.id AND
devices_LOG.device_id = devices.id
INNER JOIN
manufacturers ON devices.manufacturer_id = manufacturers.id
WHERE (devices.devicestatus = '1') AND (devices_LOG.LogType = 'Out')
GROUP BY devices_LOG.device_id, manufacturers.name, devices_LOG.LogType,
devices_LOG.userName, devices_LOG.userFullname, devices.invnumber,
devices.modelname, devices.modelnumber
ORDER BY devices_LOG.device_id
非常适合只返回包含device.status =' 1'的内容的条目,但它会为具有相同device.id的内容返回多个日志条目。所以,我的查询结果看起来像这样
device_id LogDate username LogType modelname ...etc
1 11/12/2011 foo out generic
1 11/10/2011 world out generic
2 9/10/2011 hello out generic3
2 8/9/2011 bye out generic3
当我需要它时:
device_id LogDate username LogType modelname ...etc
1 11/12/2011 foo out generic
2 9/10/2011 hello out generic3
我尝试在LogDate上使用MAX,尝试分组,选择不同等等......但我无法弄明白。有什么想法吗?
我意识到我的sql语句现在非常难看,可能是因为我一直在尝试一切我能想到的,没有运气,所以任何帮助都会非常感激,谢谢
答案 0 :(得分:1)
你几乎拥有它,但要获得每个设备的最大值,你应该加入日志并找到每个设备的最大值,然后不需要分组:
SELECT devices_LOG.device_id,
devices_LOG.LogDate AS LogDate,
manufacturers.name,
devices_LOG.LogType,
devices_LOG.userName,
devices_LOG.userFullname,
devices.invnumber,
devices.modelname,
devices.modelnumber
FROM devices_LOG
INNER JOIN devices
ON devices_LOG.device_id = devices.id
AND devices_LOG.device_id = devices.id
INNER JOIN manufacturers
ON devices.manufacturer_id = manufacturers.id
JOIN (SELECT devices_LOG.device_id,
MAX(devices_LOG.LogDate) as LogDate
FROM devices_LOG
WHERE devices_LOG.LogType = 'Out'
GROUP BY devices_LOG.device_id) maxLog
ON maxLog.LogDate = devices_LOG.LogDate
WHERE (devices.devicestatus = '1')
AND (devices_LOG.LogType = 'Out')
ORDER BY devices_LOG.device_id
答案 1 :(得分:1)
我会使用此查询,可以在http://www.sqlfiddle.com/#!3/70c0e/6处看到:
;WITH Base AS
(
SELECT
D.id
, MAX(L.LogDate) AS LastLogEntry
FROM devices D
INNER JOIN devices_LOG L
ON L.device_id = D.id
WHERE D.devicestatus = '1'
GROUP BY D.id
)
SELECT
L.device_id
, B.LastLogEntry AS LogDate
, M.name
, L.LogType
, L.userName
, L.userFullname
, D.invnumber
, D.modelname
, D.modelnumber
FROM Base B
INNER JOIN devices D
ON D.id = B.id
INNER JOIN manufacturers M
ON M.id = D.manufacturer_id
INNER JOIN devices_LOG L
ON L.device_id = B.id
AND L.LogDate = B.LastLogEntry
答案 2 :(得分:0)
如果您只是按设备_LOG.device_id分组怎么办?
...
GROUP BY devices_LOG.device_id
...
答案 3 :(得分:0)
只需将日志条目包装在CTE中,并使用ROW_NUMBER和分区来获取所需的数据。
例如,如果您想要最旧的日志条目,可以将ORDER BY LogDate DESC更改为ASC。
WITH Log AS (
SELECT ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY LogDate DESC) AS RN, *
FROM Devices_LOG
WHERE LogType = 'Out'
)
SELECT DISTINCT
Log.device_id, Log.LogDate AS LogDate,
manufacturers.name, Log.LogType, Log.userName,
Log.userFullname, devices.invnumber, devices.modelname,
devices.modelnumber
FROM devices
INNER JOIN
Log ON Log.device_id = devices.id AND
Log.RN = 1
INNER JOIN
manufacturers ON devices.manufacturer_id = manufacturers.id
WHERE (devices.devicestatus = '1')
ORDER BY devices.device_id
答案 4 :(得分:0)
我认为这是一个使用DENSE_RANK()和CTE的好地方。
WITH LOG as
(
SELECT devices_LOG.*,
DENSE_RANK() over (partition by device_id order by device_id asc, LogDate desc) as nRank
FROM devices_LOG
WHERE nRank = 1
)
SELECT DISTINCT
LOG.device_id, LOG.LogDate AS LogDate,
manufacturers.name, LOG.LogType, LOG.userName,
LOG.userFullname, devices.invnumber, devices.modelname,
devices.modelnumber
FROM LOG ---Notice I have changed which table you are selecting from.
INNER JOIN
devices ON LOG.device_id = devices.id
INNER JOIN
manufacturers ON devices.manufacturer_id = manufacturers.id
WHERE (devices.devicestatus = '1') AND (LOG.LogType = 'Out')
GROUP BY LOG.device_id, manufacturers.name, LOG.LogType,
LOG.userName, LOG.userFullname, devices.invnumber,
devices.modelname, devices.modelnumber
ORDER BY LOG.device_id
答案 5 :(得分:0)
您的问题出在制造商表中。它有两个名称值。 manufacturers.name为用户名 美孚/世界 你好/再见
这就是你看到两行的原因。它不是设备日志/最大问题。
如果我错过任何事情,请纠正我。 (我按照你的代码顺序)