0

Trying to understand MySQL logic

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

My logic. If I want to see all records except records where RecordDay = 02 and RecordMonth = 04 and RecordYear = 2013 (do not want to see records where date is 02.April, 2013), I write query like WHERE CAST(RecordDay AS UNSIGNED) != ? AND CAST(RecordMonth AS UNSIGNED) != ? AND CAST(RecordYear AS UNSIGNED) != ?. Like if I want to see, I write the same query with =. For = query works, but for != does not.

Now understand that with the query MySQL goes through columns and rows and excludes results where RecordDay = 02, RecordMonth = 04, RecordYear = 2013. With the query I as if tell I do not want to see results where...

See that this query WHERE (CAST(RecordDay AS UNSIGNED) != ? OR CAST(RecordMonth AS UNSIGNED) != ? OR CAST(RecordYear AS UNSIGNED) != ?) works. But do not understand why it works.

What does MySQL do? Goes through columns and rows, find row where RecordDay = 02, then check what values are in RecordMonth and RecordYear...

Found explanation

The AND operator displays a record if both the first condition AND the second condition are true. In the same way should be The AND operator **does not** display a record if both the first condition AND the second condition are true.

The OR operator displays a record if either the first condition OR the second condition is true.

And how with > REGEXP-contains?

Mess in my head....

4

2 回答 2

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'
于 2013-07-04T13:07:30.423 回答
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 日了。只要日年与日期的值匹配,就是那个日期,否则不是。因此,在自然语言中,您也可以看到andor之间的这种差异,只要您的描述非常精确,而我们人类通常不会,因为我们通过上下文理解的大部分含义。

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

*) 当涉及到包含任何值的行时,情况并不完全相同NULL,但那是完全不同的故事。

于 2013-07-04T13:07:10.270 回答