MySQL AND具有多个值和列。试图理解MySQL逻辑

时间:2013-07-04 12:12:17

标签: mysql

尝试理解MySQL逻辑

| RecordDay | RecordMonth | RecordYear
----------------------------------------
  02        |   04        |   2013    
  03        |   05        |   2014
  04        |   06        |   2015

我的逻辑。如果我想查看除RecordDay = 02和RecordMonth = 04和RecordYear = 2013的记录之外的所有记录(不希望看到日期为02.April,2013的记录),我写了WHERE CAST(RecordDay AS UNSIGNED) != ? AND CAST(RecordMonth AS UNSIGNED) != ? AND CAST(RecordYear AS UNSIGNED) != ?之类的查询。就像我想看到的一样,我用=编写了相同的查询。对于=查询有效,但!=没有。

现在明白,通过查询MySQL遍历列和行并排除RecordDay = 02,RecordMonth = 04,RecordYear = 2013的结果。使用查询我就像告诉我不希望看到结果......

看到此查询WHERE (CAST(RecordDay AS UNSIGNED) != ? OR CAST(RecordMonth AS UNSIGNED) != ? OR CAST(RecordYear AS UNSIGNED) != ?)有效。但不明白它为什么会起作用。

MySQL做什么?遍历列和行,找到RecordDay = 02的行,然后检查RecordMonthRecordYear中的值...

找到解释

The AND operator displays a record if both the first condition AND the second condition are true.同样应该是The AND operator **does not** display a record if both the first condition AND the second condition are true.

如果第一个条件或第二个条件为真,则OR运算符显示记录。

如何使用> REGEXP - 包含?

乱糟糟的......

2 个答案:

答案 0 :(得分:2)

以下是有关如何处理日期信息的一些建议。

取出所有数据很简单。

SELECT RecordDay, RecordMonth, RecordYear
  FROM t

忘了铸造。 MySQL知道这样做。

然后,假设你只想在2013年包含记录。你这样做。

SELECT RecordDay, RecordMonth, RecordYear
  FROM t
 WHERE RecordYear = 2013

易。

现在,假设您要包含年/月/日= 2013/4/2的记录。使用WHERE / AND执行此操作,因为您希望满足所有条件为了选择记录。

SELECT RecordDay, RecordMonth, RecordYear
  FROM t
 WHERE RecordYear = 2013
   AND RecordMonth = 4
   AND RecordDay = 2

从你的桌子上抓住一条记录。看这里。 http://sqlfiddle.com/#!2/c75d6/14/0

接下来,您希望排除而不是包含符合所有这三个条件的记录(WHERE ... AND ...... AND ......)这一点点逻辑可以解决问题。 http://sqlfiddle.com/#!2/c75d6/15/0

SELECT RecordDay, RecordMonth, RecordYear
  FROM t
 WHERE NOT (
                 RecordYear = 2013
             AND RecordMonth = 4
             AND RecordDay = 2
            )

现在,根据布尔代数的规则,你可以对表达式进行简单的转换。亚里士多德,奥卡姆的威廉和德摩根都认为这一点。 http://en.wikipedia.org/wiki/De_Morgan%27s_laws。例如

  NOT (a AND b AND c)

可以转换为

 (NOT a) OR (NOT b) OR (NOT c)

在SQL中,这是这样写的。见http://sqlfiddle.com/#!2/c75d6/16/0

SELECT RecordDay, RecordMonth, RecordYear
  FROM t
 WHERE NOT(RecordYear = 2013)
    OR NOT(RecordMonth = 4)
    OR NOT(RecordDay = 2)

最后,我们可以将NOT(RecordYear = 2013)重写为RecordYear != 2013。这样做我们得到了这个:http://sqlfiddle.com/#!2/c75d6/17/0

SELECT RecordDay, RecordMonth, RecordYear
  FROM t
 WHERE RecordYear != 2013
    OR RecordMonth != 4
    OR RecordDay != 2

这就是说,选择满足这三个不等式条件中的一个或多个的任何行。

从本质上讲,SQL语言的WHERE部分是一个布尔表达式引擎,用于处理行集。有多种方法可以编写布尔表达式,其中许多方法都适用于SQL。

最后,请考虑使用实际日期。 SQL有很多好处来处理它们。见http://sqlfiddle.com/#!2/c75d6/9/0

注意这一点SQL代码。

SELECT CAST(CONCAT_WS('-', RecordYear,RecordMonth,RecordDay) AS DATE) RecordDate

这会将您的离散日/月/日日期表示转换为DATE对象,这对于从最新到最早订购日期等各种事情非常方便...

 ORDER BY RecordDate DESC

你可以做日期算术。例如,您可以从4月2日前的8天内获取记录,就像这样。 http://sqlfiddle.com/#!2/c75d6/13/0

 WHERE RecordDate >= '2013-04-02' - INTERVAL 8 DAY
   AND RecordDate <= '2013-04-02'

答案 1 :(得分:1)

如果您反转逻辑,则需要or而不是and,或者您可以使用not来反转整个表达式。

因此,您可以使用比较来查看该行是否与日期匹配,然后使用NOT来获取那些行,而不是所有其他行。

WHERE NOT (day = 2 AND month = 4 AND year = 2013)

基本上*)与:

相同
WHERE day != 2 OR month != 4 OR year != 2013

毕竟,只要 年不同,它就不再是2013年4月2日了。一天年匹配日期的值,它就是那个日期,否则就不是。所以在自然语言中你也可以看到之间的区别,只要你在描述中非常精确,我们人类通常不会这样,因为大多数我们通过语境理解的意义。

布尔逻辑实际上是程序员无法与“普通”人交流的主要原因之一。 ;)

*)对于任何值包含NULL的行,它并不完全相同,但这完全是另一个故事。