【发布时间】:2018-06-21 03:41:53
【问题描述】:
我的查询:
$units = DB::table('units')
->join('locations', 'locations.id', '=', 'units.location_id')
->join('castles', 'castles.id', '=', 'units.castle_id')
->join('unit_types', 'unit_types.id', '=', 'units.unit_type_id')
->select('units.location_id',
'units.previous_location_id',
'units.id as unit_id',
'units.castle_id',
'castles.guild_id',
'units.unit_type_id',
'units.current_health',
'unit_types.damage',
'unit_types.range')
->get()
->groupBy('location_id', 'castle_id');
产生一些类似这样的测试数据:
{
"1": [
{
"location_id": 1,
"previous_location_id": 1,
"unit_id": 2,
"castle_id": 1,
"guild_id": null,
"unit_type_id": 3,
"current_health": 90,
"damage": 10,
"range": 3
}
],
"2": {
"1": {
"location_id": 2,
"previous_location_id": 2,
"unit_id": 3,
"castle_id": 2,
"guild_id": null,
"unit_type_id": 5,
"current_health": 100,
"damage": 20,
"range": 2
},
"6": {
"location_id": 2,
"previous_location_id": 5,
"unit_id": 7,
"castle_id": 5,
"guild_id": null,
"unit_type_id": 15,
"current_health": 180,
"damage": 20,
"range": 3
}
},
"3": {
"2": {
"location_id": 3,
"previous_location_id": 3,
"unit_id": 4,
"castle_id": 3,
"guild_id": null,
"unit_type_id": 1,
"current_health": 100,
"damage": 10,
"range": 1
},
"3": {
"location_id": 3,
"previous_location_id": 3,
"unit_id": 5,
"castle_id": 3,
"guild_id": null,
"unit_type_id": 1,
"current_health": 100,
"damage": 10,
"range": 1
}
},
"4": {
"5": {
"location_id": 4,
"previous_location_id": 4,
"unit_id": 8,
"castle_id": 4,
"guild_id": null,
"unit_type_id": 20,
"current_health": 300,
"damage": 40,
"range": 2
},
"7": {
"location_id": 4,
"previous_location_id": 1,
"unit_id": 1,
"castle_id": 1,
"guild_id": null,
"unit_type_id": 1,
"current_health": 100,
"damage": 10,
"range": 1
}
},
"5": {
"4": {
"location_id": 5,
"previous_location_id": 5,
"unit_id": 6,
"castle_id": 5,
"guild_id": null,
"unit_type_id": 15,
"current_health": 180,
"damage": 20,
"range": 3
}
}
}
我正在尝试找到一种方法来限制查询,以便我只得到location_id 相同但castle_id 不同的结果,如下所示:
{
"2": {
"1": {
"location_id": 2,
"previous_location_id": 2,
"unit_id": 3,
"castle_id": 2,
"guild_id": null,
"unit_type_id": 5,
"current_health": 100,
"damage": 20,
"range": 2
},
"6": {
"location_id": 2,
"previous_location_id": 5,
"unit_id": 7,
"castle_id": 5,
"guild_id": null,
"unit_type_id": 15,
"current_health": 180,
"damage": 20,
"range": 3
}
},
"4": {
"5": {
"location_id": 4,
"previous_location_id": 4,
"unit_id": 8,
"castle_id": 4,
"guild_id": null,
"unit_type_id": 20,
"current_health": 300,
"damage": 40,
"range": 2
},
"7": {
"location_id": 4,
"previous_location_id": 1,
"unit_id": 1,
"castle_id": 1,
"guild_id": null,
"unit_type_id": 1,
"current_health": 100,
"damage": 10,
"range": 1
}
},
}
我尝试了类似 ->whereColumn('units.location_id', '<>', 'units.castle_id') 的方法,但在 castle_id 碰巧有类似密钥的情况下不起作用。
编辑
当我在给定位置有超过 1 个 castle_id 时,这个原始 SQL 会告诉我:
SELECT location_id,
COUNT(DISTINCT castle_id)
FROM units
GROUP BY location_id
ORDER BY COUNT DESC;
但我只想像这样直接选择那些行:
SELECT location_id,
FROM units
WHERE (DISTINCT castle_id);
编辑#2
这是一个假设:
-
units有 100 行 - 10行有
location_id: 1 - 20行有
location_id: 3 - 等等……
在有 location_id: 1 的 10 行中,所有 10 行也有 castle_id: 76
在有location_id: 3的20行中,有13行有castle_id: 99,其中7行有castle_id: 42
我正在尝试确定行何时具有相同的 location_id 但 castle_id 不相同。
在这种情况下,我会跳过 10 行,保留符合我的条件的 20 行,然后检查剩余的 70 行。
编辑 #3 这是一个按要求提供的 SQL Fiddle:http://sqlfiddle.com/#!9/fad08
编辑 #4 这是我的新查询:
$units = DB::table('units AS u1')
->select('u1.location_id',
'u1.previous_location_id',
'u1.id as unit_id',
'u1.castle_id',
'c1.guild_id',
'u1.unit_type_id',
'u1.current_health',
'ut.damage',
'ut.range')
->distinct()
->join('units AS u2', 'u1.location_id', '=', 'u2.location_id')
->join('castles AS c1', 'c1.id', '=', 'u1.castle_id')
->join('castles AS c2', 'c2.id', '=', 'u2.castle_id')
->join('unit_types AS ut', 'ut.id', '=', 'u1.unit_type_id')
->whereColumn([
['u1.castle_id', '<>', 'u2.castle_id'],
['c1.guild_id', '<>', 'c2.guild_id']
])
->orderBy('location_id')
->get();
echo $units;
基于 fubar 的回答,在 guild_id 相同时添加了另一个约束。
【问题讨论】:
-
请详细说明您要达到的目标
-
@AndréMarcondesTeixeira 我用一个假设编辑了我的原始帖子,希望能阐明我在查询中想要实现的目标。感谢您的帮助!
-
你能用种子数据创建一个 SQL 小提琴吗?这可能有助于可视化数据,并且肯定有助于测试查询。
-
@fubar 我在原始帖子中添加了一个 SQL 小提琴。我正在使用 laravel 迁移来建立我的数据库,但我没有太多的 SQL 经验,所以我让它有点简单......你需要我添加更多表或定义主键吗?
-
@deja 真棒。澄清一下,
get the results where location_id is the same but castle_id is different- 根据您刚刚创建的 SQL 小提琴,您希望返回哪些行?对于第 4 行和第 5 行,位置和城堡 id 相同,那么是返回第 4 行、第 5 行还是两者都不返回?
标签: php sql postgresql laravel