使用Not Where条件编写雄辩的查询版本

时间:2018-10-02 15:28:39

标签: php mysql laravel eloquent

我该如何雄辩地编写此查询?

SELECT * 
FROM  `table`
WHERE 
    !(
        ((col0 = 'AA') AND (col1 = 'AA'))
     OR
        ((col0 = 'BB') AND (col1 = 'BB'))
    )

这是我的口才版本:

        $query->where(function ($sub_query){
            $sub_query->orWhere(function ($sub_sub_query){
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
            });
            $sub_query->orWhere(function ($sub_sub_query){
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
            });
        });

我什么都没找到!(XXX)

谢谢!

编辑:

我找到了解决方法:

https://laracasts.com/discuss/channels/eloquent/negate-entire-nested-where-clause

有代码:

        $query->where(function ($sub_query){
            $sub_query->orWhere(function ($sub_sub_query){
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
            });
            $sub_query->orWhere(function ($sub_sub_query){
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
                $sub_sub_query->where(function ($sub_sub_query){
                    // Some stuff
                });
            });
        }, null, null, 'AND NOT');

4 个答案:

答案 0 :(得分:0)

尝试在extension ClosedRange where Element: BinaryFloatingPoint, Element.RawSignificand: FixedWidthInteger { public func random() -> Element { return Element.random(in: self) } } extension ClosedRange where Element: FixedWidthInteger { public func random() -> Element { return Element.random(in: self) } } /// SCNVector3 Operators /// /// Random extension SCNVector3 { public init<T:BinaryFloatingPoint>(_ x: T, _ y: T, _ z: T) { self.init() self.x = CGFloat(x) self.y = CGFloat(y) self.z = CGFloat(z) } public init<T:FixedWidthInteger>(_ x: T, _ y: T, _ z: T) { self.init() self.x = CGFloat(x) self.y = CGFloat(y) self.z = CGFloat(z) } public static func random<T: BinaryFloatingPoint>(_ xrange: ClosedRange<T>, _ yrange: ClosedRange<T>, _ zrange: ClosedRange<T>) -> SCNVector3 where T.RawSignificand: FixedWidthInteger { let x = ClosedRange<T>.Element.random(in: xrange) let y = ClosedRange<T>.Element.random(in: yrange) let z = ClosedRange<T>.Element.random(in: zrange) return SCNVector3(x, y, z) } public static func random<T: FixedWidthInteger>(_ xrange: ClosedRange<T>, _ yrange: ClosedRange<T>, _ zrange: ClosedRange<T>) -> SCNVector3 { let x = ClosedRange<T>.Element.random(in: xrange) let y = ClosedRange<T>.Element.random(in: yrange) let z = ClosedRange<T>.Element.random(in: zrange) return SCNVector3(x, y, z) } } 中进行query的此Model更改,以便您table model进行检查并test

$object = Model::where([['col0' ,'<>', 'AA'],['col1','<>','AA']])
->orWhere([['col0','<>','BB'],['col1','<>', 'BB']])->get();

答案 1 :(得分:0)

您可以将查询变成这样:

SELECT * 
FROM  `table`
WHERE 
    (
        ((col0 != 'AA') OR (col1 != 'AA'))
     AND
        ((col0 != 'BB') OR (col1 != 'BB'))
    )

给出相同的结果,并且可以这样表示:

    $query->where(function ($sub_query){
        $sub_query->Where(function ($sub_sub_query){
            $sub_sub_query->where('col0' ,'!=', 'AA')
                          ->Orwhere('col1' ,'!=', 'AA');
        });
        $sub_query->Where(function ($sub_sub_query){
            $sub_sub_query->where('col0' ,'!=', 'BB')
                          ->Orwhere('col1' ,'!=', 'BB');
        });
    });

答案 2 :(得分:0)

WHERE
!(
    ((col0 = 'AA') AND (col1 = 'AA'))
  OR
    ((col0 = 'BB') AND (col1 = 'BB'))
)

等同于

WHERE
    !((col0 = 'AA') AND (col1 = 'AA')) 
  AND
    !((col0 = 'BB') AND (col1 = 'BB'))

因为不是(A或B)===不是A并且不是B

简化更多,它变成

WHERE
    ( !(col0 = 'AA') OR !(col1 = 'AA') )  
  AND
    ( !(col0 = 'BB') OR !(col1 = 'BB') )

因为不是A和B ===不是A或不是B

因此可以像这样构建查询。

$q->where(function($q) {
    $q->where('col0','!=','AA')->orWhere('col1','!=','AA');
})->where(function($q) {
    $q->where('col0','!=','BB')->orWhere('col1','!=','BB');
});

答案 3 :(得分:0)

我找到了解决方法:https://laracasts.com/discuss/channels/eloquent/negate-entire-nested-where-clause

有代码:

    $query->where(function ($sub_query){
        $sub_query->orWhere(function ($sub_sub_query){
            $sub_sub_query->where(function ($sub_sub_query){
                // Some stuff
            });
            $sub_sub_query->where(function ($sub_sub_query){
                // Some stuff
            });
        });
        $sub_query->orWhere(function ($sub_sub_query){
            $sub_sub_query->where(function ($sub_sub_query){
                // Some stuff
            });
            $sub_sub_query->where(function ($sub_sub_query){
                // Some stuff
            });
        });
    }, null, null, 'AND NOT');