Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:按一组行限制,而不是按一行限制_Mysql_Sql - Fatal编程技术网

MySQL:按一组行限制,而不是按一行限制

MySQL:按一组行限制,而不是按一行限制,mysql,sql,Mysql,Sql,我有一个如下所示的MySQL表。id和name字段仅用于帮助识别行,l表示许多没有相关数据的其他字段,lat和lng用于查找重复条目 CREATE TABLE v (`id` int, `lat` int, `lng` int, `l` varchar(3), `name` varchar(8)) ; INSERT INTO v (`id`, `lat`, `lng`, `l`, `name`) VALUES ( 1, 12, 12, 'a', 'group1-1'),

我有一个如下所示的MySQL表。
id
name
字段仅用于帮助识别行,
l
表示许多没有相关数据的其他字段,
lat
lng
用于查找重复条目

CREATE TABLE v
    (`id` int, `lat` int, `lng` int, `l` varchar(3), `name` varchar(8))
;

INSERT INTO v
    (`id`, `lat`, `lng`, `l`, `name`)
VALUES
    ( 1, 12, 12, 'a', 'group1-1'),
    ( 2, 12, 12, 'b', 'group1-2'),
    ( 3, 13, 12, 'c', 'single1'),
    ( 4, 13, 13, 'd', 'group2-1'),
    ( 5, 13, 13, 'e', 'group2-2'),
    ( 6, 13, 13, 'f', 'group2-3'),
    ( 7, 10, 13, 'g', 'group3-1'),
    ( 8, 10, 13, 'h', 'group3-2'),
    ( 9, 11, 12, 'h', 'group4-1'),
    (10, 11, 12, 'h', 'group4-2'),
    (11, 10, 14, 'i', 'group5-1'),
    (12, 10, 14, 'j', 'group5-2'),
    (13, 10, 14, 'j', 'group5-3')
;
现在,我想得到多行具有相同lat和lng值的所有行(我们称之为组):

产出:

ID  LAT LNG L   NAME
1   12  12  a   group1-1
2   12  12  b   group1-2
4   13  13  d   group2-1
5   13  13  e   group2-2
6   13  13  f   group2-3
7   10  13  g   group3-1
8   10  13  h   group3-2
9   11  12  h   group4-1
10  11  12  h   group4-2
11  10  14  i   group5-1
12  10  14  j   group5-2
13  10  14  j   group5-3
到目前为止效果很好,除了“single1”行之外,所有行都是按组选择和排序的

现在我想添加一个限制,以形成此数据的不同页面。但同一组的所有行都需要在同一页上(但不是每个组一页,一页上实际有多少行并不重要,只是不要太多)。我不认为用限制语句就能做到这一点,所以我开始写我自己的:

SET @grp := 0, @last_lat := '', @last_lng := '';

SELECT * FROM (
 SELECT v.*,
  @grp := IF((@last_lat = lat) && (@last_lng = lng), @grp, @grp + 1) AS grp,
  @last_lat := lat AS llat,
  @last_lng := lng AS llng
 FROM v
  INNER JOIN (
   SELECT lat, lng
   FROM v
   GROUP BY lat, lng
   HAVING COUNT(*) > 1
   ) AS vg
   USING (lat, lng) 
 ORDER BY lat, lng
) AS vv
WHERE grp BETWEEN 0 AND 7
ORDER BY grp
;
此查询将显示零件输出此数据的位置:

ID  LAT LNG L   NAME        GRP LLAT    LLNG
1   12  12  a   group1-1    6   12  12
2   12  12  b   group1-2    6   12  12
5   13  13  e   group2-2    7   13  13
6   13  13  f   group2-3    7   13  13
4   13  13  d   group2-1    7   13  13
7   10  13  g   group3-1    8   10  13
8   10  13  h   group3-2    8   10  13
10  11  12  h   group4-2    9   11  12
9   11  12  h   group4-1    9   11  12
13  10  14  j   group5-3    10  10  14
11  10  14  i   group5-1    10  10  14
12  10  14  j   group5-2    10  10  14
我们的想法是更改grp所在行中的值,每个页面的grp介于0和7之间。但是组中的数字不是从1开始的,我也不明白为什么(这使得它无法用于第一页)。根据整个数据中有多少组,起始编号是不同的。所以我需要的是,grp列从1开始,然后一直到+1

这个查询有什么问题,有没有更好的方法


你可以在这里玩这个查询:

你有能力改变模式吗?最好将该名称列规范化为几列:而不是

id | lat | lng | l | name
你的专栏应该是

id | lat | lng | l | groupOrSingle | groupid | memberid

那么,编写查询就很简单了,更不用说运行方式了,因为您可以为正在查询的分组信息编制索引。

您有能力更改模式吗?最好将该名称列规范化为几列:而不是

id | lat | lng | l | name
SET @grp := 0, @last_lat := '', @last_lng := '';

SELECT vv.*,@grp-grp+1 as orgGrp FROM (
 SELECT v.*,
  @grp := IF((@last_lat = lat) && (@last_lng = lng), @grp, @grp + 1) AS grp,
  @last_lat := lat AS llat,
  @last_lng := lng AS llng
 FROM v
  INNER JOIN (
   SELECT lat, lng
   FROM v
   GROUP BY lat, lng
   HAVING COUNT(*) > 1
   ) AS vg
   USING (lat, lng) 
 ORDER BY lat, lng
) AS vv

ORDER BY orgGrp
;
你的专栏应该是

id | lat | lng | l | groupOrSingle | groupid | memberid
然后编写查询将是一件小事,更不用说运行方式了,因为您将能够索引您正在查询的分组信息

SET @grp := 0, @last_lat := '', @last_lng := '';

SELECT vv.*,@grp-grp+1 as orgGrp FROM (
 SELECT v.*,
  @grp := IF((@last_lat = lat) && (@last_lng = lng), @grp, @grp + 1) AS grp,
  @last_lat := lat AS llat,
  @last_lng := lng AS llng
 FROM v
  INNER JOIN (
   SELECT lat, lng
   FROM v
   GROUP BY lat, lng
   HAVING COUNT(*) > 1
   ) AS vg
   USING (lat, lng) 
 ORDER BY lat, lng
) AS vv

ORDER BY orgGrp
;


你能根据样本数据发布预期结果吗?@PM77-1我添加了输出和一些解释。你能根据样本数据发布预期结果吗?@PM77-1我添加了输出和一些解释。不,我不能更改架构。这些组实际上并不是我想要的-我通过这个查询来搜索应该被修复的错误条目。此外,这里的名称只是为了更容易看到它是哪些数据。在真实的数据中,它们是不同的,与任何组都无关。不,我不能更改模式。这些组实际上并不是我想要的-我通过这个查询来搜索应该被修复的错误条目。此外,这里的名称只是为了更容易看到它是哪些数据。在实际数据中,它们与任何组都不同且无关。如果您的组始终有5列,则初始化@grp:=-5。。这会起作用的,因为小组的规模总是不同的。但是你的查询无法工作。你能解释一下它是怎么工作的吗?谢谢在这个-fiddle中,子查询首先执行,结果是一组5个。当您从“vv”中选择时,将再次检查条件,如果lat和lng与前一个不同,将添加1。如果您能够从子查询中初始化max(组号)的负数,则可以完成此操作。如果您的组始终有5列,则初始化@grp:=-5。。这会起作用的,因为小组的规模总是不同的。但是你的查询无法工作。你能解释一下它是怎么工作的吗?谢谢在这个-fiddle中,子查询首先执行,结果是一组5个。当您从“vv”中选择时,将再次检查条件,如果lat和lng与前一个不同,将添加1。如果您能够从子查询中初始化max(组号)的负数,那么它将完成此任务。