我正在尝试从表(tblRecords
)中进行选择,并排除具有在不同表(tblPerson
)中重复的值的行。作为一个直观的例子:
当前表:
tblRecords: tblPerson:
+------------+-------------+ +------------+------------+
| CustomerID | OrderID | | PersonID | UserID |
+------------+-------------+ +------------+------------+
| 101 | 1 | | 8 | 3004 |
| 18 | 7 | | 5 | 81 |
| 8 | 1 | | 19 | 100 |
| 100 | 2 | | 19 | 101 |
+------------+-------------+ +------------+------------+
期望的输出:
+------------+-------------+
| CustomerID | OrderID |
+------------+-------------+
| 18 | 7 |
| 8 | 1 |
+------------+-------------+
这是一个简化的例子,请原谅不良桌面设计的迹象。由于PersonID
'19'在tblPerson
中出现多次,我想排除tblRecords
的所有结果,其中CustomerID
与UserID
相同对应重复的PersonID
(因此排除100和101)。
我认为解决方案是在查询的WHERE子句中使用NOT EXISTS
,而不是按重复值进行分组。这是我写的查询没有按预期工作:
SELECT *
FROM tblRecords
WHERE NOT EXISTS (
SELECT PersonID
FROM tblPeople
GROUP BY PersonID
HAVING COUNT(PersonID) > 1
)
我不明白如何修复查询,因此它知道从tblRecords
排除结果CustomerID
值出现在PersonID
中重复的tblPerson
旁边。此时,子查询选择我想要排除的确切值。我只是不知道他们是如何在CustomerID
中逻辑搜索的。
答案 0 :(得分:4)
您可以在 <?php
$data = json_decode('[
{
"id": 1,
"value1": 5,
"value2": 10
},
{
"id": 2,
"value1": 50,
"value2": 100
},
{
"id": 1,
"value1": 1,
"value2": 2
},
{
"id": 2,
"value1": 15,
"value2": 20
},
{
"id": 3,
"value1": 15,
"value2": 20
}
]');
//print_r(array_group_by($data,'id'));
print_r(array_sum_by($data,'id',['value1','value2']));
//print_r(array_sum(array_column($data,'value1')));
function array_sum_by($array,$group,$keys)
{
$groupeddata = array_group_by($array,$group);
return array_map(function($items) use($group,$keys) {
foreach($keys as $key)
{
$values[$key] = array_sum(array_column($items,$key));
}
$first = array_shift($items);
if(is_object( $first ) && isset( $first->{ $group } )){
$values = array_merge([ $group => $first->{ $group } ], $values);
}elseif(isset($first[$group])){
$values = array_merge([ $group => $first[$group] ], $values);
}
return $values;
},$groupeddata);
}
function array_group_by( array $array, $key )
{
if ( ! is_string( $key ) && ! is_int( $key ) && ! is_float( $key ) && ! is_callable( $key ) ) {
trigger_error( 'array_group_by(): The key should be a string, an integer, or a callback', E_USER_ERROR );
return null;
}
$func = ( is_callable( $key ) ? $key : null );
$_key = $key;
// Load the new array, splitting by the target key
$grouped = [];
foreach ( $array as $value ) {
if ( is_callable( $func ) ) {
$key = call_user_func( $func, $value );
} elseif ( is_object( $value ) && isset( $value->{ $_key } ) ) {
$key = $value->{ $_key };
} elseif ( isset( $value[ $_key ] ) ) {
$key = $value[ $_key ];
} else {
continue;
}
$grouped[ $key ][] = $value;
}
// Recursively build a nested grouping if more parameters are supplied
// Each grouped array value is grouped according to the next sequential key
if ( func_num_args() > 2 ) {
$args = func_get_args();
foreach ( $grouped as $key => $value ) {
$params = array_merge( [ $value ], array_slice( $args, 2, func_num_args() ) );
$grouped[ $key ] = call_user_func_array( 'array_group_by', $params );
}
}
return $grouped;
}
查询的where
子句中添加相关性:
not exists()
对于更新的问题,请使用SELECT *
FROM ISOW.dbo.tblRecords r
WHERE NOT EXISTS (
SELECT PersonID
FROM ISOW.dbo.tblPeople p
where p.PersonID= r.CustomerID
GROUP BY PersonID
HAVING COUNT(PersonID) > 1
)
和not exists()
:
exists()
rextester演示:http://rextester.com/DNWK20907
返回:
select r.CustomerID, r.OrderID
from dbo.tblRecords r
where not exists (
select PersonID
from dbo.tblPeople p
where p.UserID= r.CustomerID
and exists (
select 1
from dbo.tblPeople i
where i.PersonID = p.PersonID
and i.UserID <> p.UserID
)
)