- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有 2 个表(pcgroup 和客户端 pc)。假设今天是 11 月 24 日,我需要仅使用 mySQL 查找最近 2 天哪台 PC 在线以及哪台 PC 不在线。
INSERT INTO pcgroup(id, groupName)
VALUES(1, 'defaultGroup');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime)
VALUES(1, 1, 'pc1', '2011-11-24');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime)
VALUES(2, 1, 'pc2', '2011-11-24');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime)
VALUES(3, 1, 'pc3', '2011-11-20');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime)
VALUES(4, 1, 'pc4', '2011-11-20');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime)
VALUES(5, 1, 'pc5', '2011-11-20');
这是我现在的查询
SELECT DISTINCT
pcgroup.id AS pcGroupID, pcgroup.groupName,
online.onlinePC, offline.offlinePC
FROM
(
SELECT
pcgroup.Id, pcGroup.groupName
FROM
pcgroup
WHERE
(pcgroup.Id = 1)
) pcgroup
LEFT JOIN
(
SELECT
clientpc.Id, clientpc.pcGroupId, clientpc.clientPcName AS onlinePC
FROM
clientpc
WHERE
DateDiff(CURDATE(),clientpc.lastOnlineTime) <= 2
AND
DateDiff(CURDATE(),clientpc.lastOnlineTime) IS NOT NULL
) online
ON
pcgroup.Id = online.pcGroupId
LEFT JOIN
(
SELECT
clientpc.Id, clientpc.pcGroupId, clientpc.clientPcName AS offlinePC
FROM
clientpc
WHERE
(DateDiff(CURDATE(),clientpc.lastOnlineTime) > 2
OR
DateDiff(CURDATE(),clientpc.lastOnlineTime) IS NULL)
) offline
ON pcgroup.Id = offline.pcGroupId
这是我得到的结果
*pcGroupID groupName onlinePC offlinePC*
1 defaultGroup pc1 pc3
1 defaultGroup pc1 pc4
1 defaultGroup pc1 pc5
1 defaultGroup pc2 pc3
1 defaultGroup pc2 pc4
1 defaultGroup pc2 pc5
但是,我需要的是这样的东西
*pcGroupID groupName onlinePC offlinePC*
1 defaultGroup pc1 pc3
1 defaultGroup pc2 pc4
1 defaultGroup pc5
所以我的问题是,这可以实现吗?如果是,如何。已经处理此查询 2 天了。所以,如果你们能帮助我,我真的很感激。
最佳答案
我启动了一个 MySQL 实例并模拟了 Postgres 解决方案中使用的 rowid。创建脚本:
CREATE TABLE pcgroup(id int, groupName varchar(64));
CREATE TABLE clientpc(id int, pcGroupId int, clientPcName varchar(64), lastOnlineTime date);
INSERT INTO pcgroup(id, groupName) VALUES(1, 'defaultGroup');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(1, 1, 'pc1', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(2, 1, 'pc2', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(3, 1, 'pc3', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(4, 1, 'pc4', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(5, 1, 'pc5', CURRENT_DATE-4);
INSERT INTO pcgroup(id, groupName) VALUES(2, 'group2');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(6, 2, 'pc6', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(7, 2, 'pc7', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(8, 2, 'pc8', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(9, 2, 'pc9', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(10, 2, 'pc10', CURRENT_DATE);
脚本(遵循与 Postgres 解决方案相同的逻辑):
-- Apply sort to union
SELECT pcGroupID, groupName, onlinePC, offlinePC
FROM (
SELECT online.pcGroupID, online.groupName, online.clientPcName AS onlinePC, IFNULL(offline.clientPcName, '-') AS offlinePC
FROM (-- Apply a groupName-based row number to the list of "online" PCs
SELECT pcGroupID, groupName, clientPcName, lastOnlineTime
,if(@lastGroupID!=pcGroupID
,CONCAT_WS('_', pcGroupID, @curRow := 1)
,CONCAT_WS('_', pcGroupID, @curRow := @curRow + 1)) AS row_number
,@lastGroupID := pcGroupID
FROM (-- Filter to the list of online PCs
SELECT g.id AS pcGroupID, g.groupName, c.clientPcName, c.lastOnlineTime
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND c.lastOnlineTime >= CURRENT_DATE - 2
ORDER BY g.id, c.clientPcName ) x
,(SELECT @curRow := 0) r ) AS online
LEFT OUTER JOIN (
-- Apply a groupName-based row number to the list of "offline" PCs
SELECT pcGroupID, groupName, clientPcName, lastOnlineTime
,if(@lastGroupID!=pcGroupID
,CONCAT_WS('_', pcGroupID, @curRow := 1)
,CONCAT_WS('_', pcGroupID, @curRow := @curRow + 1)) AS row_number
,@lastGroupID := pcGroupID
FROM (-- Filter to the list of offline PCs
SELECT g.id AS pcGroupID, g.groupName, c.clientPcName, c.lastOnlineTime
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND c.lastOnlineTime < CURRENT_DATE - 2
ORDER BY g.id, c.clientPcName ) x
,(SELECT @curRow := 0) r ) AS offline
ON (online.row_number = offline.row_number)
UNION
SELECT offline.pcGroupID, offline.groupName, IFNULL(online.clientPcName, '~') AS onlinePC, offline.clientPcName AS offlinePC
FROM (-- Apply a groupName-based row number to the list of "online" PCs
SELECT pcGroupID, groupName, clientPcName, lastOnlineTime
,if(@lastGroupID!=pcGroupID
,CONCAT_WS('_', pcGroupID, @curRow := 1)
,CONCAT_WS('_', pcGroupID, @curRow := @curRow + 1)) AS row_number
,@lastGroupID := pcGroupID
FROM (-- Filter to the list of online PCs
SELECT g.id AS pcGroupID, g.groupName, c.clientPcName, c.lastOnlineTime
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND c.lastOnlineTime >= CURRENT_DATE - 2
ORDER BY g.id, c.clientPcName ) x
,(SELECT @curRow := 0) r ) AS online
RIGHT OUTER JOIN (
-- Apply a groupName-based row number to the list of "offline" PCs
SELECT pcGroupID, groupName, clientPcName, lastOnlineTime
,if(@lastGroupID!=pcGroupID
,CONCAT_WS('_', pcGroupID, @curRow := 1)
,CONCAT_WS('_', pcGroupID, @curRow := @curRow + 1)) AS row_number
,@lastGroupID := pcGroupID
FROM (-- Filter to the list of offline PCs
SELECT g.id AS pcGroupID, g.groupName, c.clientPcName, c.lastOnlineTime
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND c.lastOnlineTime < CURRENT_DATE - 2
ORDER BY g.id, c.clientPcName ) x
,(SELECT @curRow := 0) r ) AS offline
ON (online.row_number = offline.row_number)
) z ORDER BY pcGroupID, groupName, OnlinePC, offlinePC
结果:
1 defaultGroup pc1 pc3
1 defaultGroup pc2 pc4
1 defaultGroup ~ pc5
2 group2 pc10 pc6
2 group2 pc8 pc7
2 group2 pc9 -
-- PostgreSQL--
我在 Postgres 中试过了。这个查询看起来比实际情况更可怕。有许多功能可以缩短它:子查询分解(即使用 WITH)、伪行号生成器、完全外部连接)。我不确定 mysql 是否有那个,所以我没有使用那些函数。
我认为要点是您要的是两个并不真正相关的不同列表:onlinePCs 和 offlinePCs。您只想将两个列表并排放置。为此,您可以引入行计数伪列来创建两个列表之间的关系。第 1 步生成在线 PC 列表并计算每个组的数量(生成行标识符 _。然后根据该行标识符将其加入离线 PC 列表。如果离线 PC 多于在线 PC,离线 PC 不会出现在此列表中。这就是我们在第 4 步中再次执行整个操作的原因,但这次由离线 PC 驱动,以解决离线 PC 多于在线的情况PC。UNION 将去除重复项。
我还使用了 CURRENT_DATE 并将 2 硬编码为离线和在线之间的天数。您需要尝试一下。
创建脚本:
CREATE TABLE pcgroup(id bigint, groupName varchar);
CREATE TABLE clientpc(id bigint, pcGroupId bigint, clientPcName varchar, lastOnlineTime date);
INSERT INTO pcgroup(id, groupName) VALUES(1, 'defaultGroup');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(1, 1, 'pc1', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(2, 1, 'pc2', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(3, 1, 'pc3', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(4, 1, 'pc4', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(5, 1, 'pc5', CURRENT_DATE-4);
INSERT INTO pcgroup(id, groupName) VALUES(2, 'group2');
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(6, 2, 'pc6', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(7, 2, 'pc7', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(8, 2, 'pc8', CURRENT_DATE-4);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(9, 2, 'pc9', CURRENT_DATE);
INSERT INTO clientpc(id, pcGroupId, clientPcName, lastOnlineTime) VALUES(10, 2, 'pc10', CURRENT_DATE);
查询:
SELECT online.pcGroupID, online.groupName, online.clientPcName AS onlinePC, offline.clientPcName AS offlinePC
-- 1: Get the list of online PCs, and give them a group based pseudo rownumber
FROM (SELECT g.id AS pcGroupID, g.groupName, c.clientPcName
,g.id || '_' || row_number() OVER(PARTITION BY g.id ORDER BY g.id, c.clientPcName) AS rownum
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND lastOnlineTime > CURRENT_DATE - 2) AS online
-- 2: Get the list of offline PCs, and give them a group based pseudo rownumber
LEFT OUTER JOIN (SELECT g.id AS pcGroupID, g.groupName, c.clientPcName
,g.id || '_' || row_number() OVER(PARTITION BY g.id ORDER BY g.id, c.clientPcName) AS rownum
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND lastOnlineTime <= CURRENT_DATE - 2) AS offline
-- 3: Join the list together: this will only include rows for the number of "online" pcs that exist
ON (online.rownum = offline.rownum)
-- 4: Repeat 1-3, but this time base it on offline pcs and it will only include rows for the number of "offline" pcs that exist
-- The UNION will dump the duplicates
UNION
SELECT offline.pcGroupID, offline.groupName, online.clientPcName AS onlinePC, offline.clientPcName AS offlinePC
FROM (SELECT g.id AS pcGroupID, g.groupName, c.clientPcName
,g.id || '_' || row_number() OVER(PARTITION BY g.id ORDER BY g.id, c.clientPcName) AS rownum
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND lastOnlineTime > CURRENT_DATE - 2) AS online
RIGHT OUTER JOIN (SELECT g.id AS pcGroupID, g.groupName, c.clientPcName
,g.id || '_' || row_number() OVER(PARTITION BY g.id ORDER BY g.id, c.clientPcName) AS rownum
FROM pcgroup g
,clientpc c
WHERE c.pcGroupId = g.id
AND lastOnlineTime <= CURRENT_DATE - 2) AS offline
ON (online.rownum = offline.rownum)
结果:
pcgroupid | groupname | onlinepc | offlinepc
-----------+--------------+----------+-----------
1 | defaultGroup | pc1 | pc3
1 | defaultGroup | pc2 | pc4
1 | defaultGroup | | pc5
2 | group2 | pc10 | pc6
2 | group2 | pc8 | pc7
2 | group2 | pc9 |
(6 rows)
关于mySQL连接表重复问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8254388/
我知道这个问题可能已经被问过,但我检查了所有这些,我认为我的情况有所不同(请友善)。所以我有两个数据集,第一个是测试数据集,第二个是我保存在数据框中的预测(预测值,这就是没有数据列的原因)。我想合并两
在 .loc 方法的帮助下,我根据同一数据框中另一列中的值来识别 Panda 数据框中某一列中的值。 下面给出了代码片段供您引用: var1 = output_df['Player'].loc[out
当我在 Windows 中使用 WinSCP 通过 Ubuntu 连接到 VMware 时,它提示: The server rejected SFTP connection, but it lis
我正在开发一个使用 xml web 服务的 android 应用程序。在 wi-fi 网络中连接时工作正常,但在 3G 网络中连接时失败(未找到 http 404)。 这不仅仅发生在设备中。为了进行测
我有一个XIB包含我的控件的文件,加载到 Interface Builder(Snow Leopard 上的 Xcode 4.0.2)中。 文件的所有者被设置为 someClassController
我在本地计算机上管理 MySQL 数据库,并通过运行以下程序通过 C 连接到它: #include #include #include int main(int argc, char** arg
我不知道为什么每次有人访问我网站上的页面时,都会打开一个与数据库的新连接。最终我到达了大约 300 并收到错误并且页面不再加载。我认为它应该工作的方式是,我将 maxIdle 设置为 30,这意味着
希望清理 NMEA GPS 中的 .txt 文件。我当前的代码如下。 deletes = ['$GPGGA', '$GPGSA', '$GPGSV', '$PSRF156', ] searchquer
我有一个 URL、一个用户名和一个密码。我想在 C# .Net WinForms 中建立 VPN 连接。 你能告诉我从哪里开始吗?任何第三方 API? 代码示例将受到高度赞赏... 最佳答案 您可以像
有没有更好的方法将字符串 vector 转换为字符 vector ,字符串之间的终止符为零。 因此,如果我有一个包含以下字符串的 vector "test","my","string",那么我想接收一
我正在编写一个库,它不断检查 android 设备的连接,并在设备连接、断开连接或互联网连接变慢时给出回调。 https://github.com/muddassir235/connection_ch
我的操作系统:Centos 7 + CLOUDLINUX 7.7当我尝试从服务器登录Mysql时 [root@server3 ~]# Mysql -u root -h localhost -P 330
我收到错误:Puma 发现此错误:无法打开到本地主机的 TCP 连接:9200(连接被拒绝 - 连接(2)用于“本地主机”端口 9200)(Faraday::ConnectionFailed)在我的
请给我一些解决以下错误的方法。 这是一个聊天应用....代码和错误如下:: conversations_controller.rb def create if Conversation.bet
我想将两个单元格中的数据连接到一个单元格中。我还想只组合那些具有相同 ID 的单元格。 任务 ID 名称 4355.2 参与者 4355.2 领袖 4462.1 在线 4462.1 快速 4597.1
我经常需要连接 TSQL 中的字段... 使用“+”运算符时 TSQL 强制您处理的两个问题是 Data Type Precedence和 NULL 值。 使用数据类型优先级,问题是转换错误。 1)
有没有在 iPad 或 iPhone 应用程序中使用 Facebook 连接。 这个想法是登录这个应用程序,然后能够看到我的哪些 facebook 用户也在使用该应用程序及其功能。 最佳答案 是的。
我在连接或打印字符串时遇到了一个奇怪的问题。我有一个 char * ,可以将其设置为字符串文字的几个值之一。 char *myStrLiteral = NULL; ... if(blah) myS
对于以下数据 - let $x := "Yahooooo !!!! Select one number - " let $y := 1 2 3 4 5 6 7 我想得到
我正在看 UDEMY for perl 的培训视频,但是视频不清晰,看起来有错误。 培训展示了如何使用以下示例连接 2 个字符串: #!usr/bin/perl print $str = "Hi";
我是一名优秀的程序员,十分优秀!