Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php SQL IN()查询可以接受或语句吗_Php_Mysql - Fatal编程技术网

Php SQL IN()查询可以接受或语句吗

Php SQL IN()查询可以接受或语句吗,php,mysql,Php,Mysql,我有一个表名数据,如下所示。列mn从1到59运行,并从1开始 所以我有一个查询,它选择了10个这样的间隔 SELECT * FROM data WHERE mn IN('00','10','20','30','40','50') AND dt='2019-04-20' ORDER BY ID ASC 这样做效果很好,可以得到所需的结果。 但由于某些原因,有时需要的数据00、10、20、30等不可用,我希望能够选择下一个或前一个来代替它 假设10不可用,我希望能够在其位置选择09或11,或者假设

我有一个表名数据,如下所示。列mn从1到59运行,并从1开始 所以我有一个查询,它选择了10个这样的间隔

SELECT * FROM data WHERE mn IN('00','10','20','30','40','50') AND dt='2019-04-20' ORDER BY ID ASC
这样做效果很好,可以得到所需的结果。 但由于某些原因,有时需要的数据00、10、20、30等不可用,我希望能够选择下一个或前一个来代替它

假设10不可用,我希望能够在其位置选择09或11,或者假设20不可用,我希望能够在其位置选择19或21。 我怎么能这样做呢?我试过一个OR,在语句中它返回了一个有趣的结果。 如果您有任何帮助,我们将不胜感激。谢谢

id  mn  dt         status
---|---|----------|-----------
 1 |01 |2019-04-20|1    
 2 |02 |2019-04-20|1
 3 |03 |2019-04-20|1    
 4 |04 |2019-04-20|1
 5 |05 |2019-04-20|1    
 6 |06 |2019-04-20|1
 7 |07 |2019-04-20|1    
 8 |08 |2019-04-20|1
 9 |09 |2019-04-20|1    
 10|10 |2019-04-20|1
 11|11 |2019-04-20|1    
 12|12 |2019-04-20|1
 13|13 |2019-04-20|1    
 14|14 |2019-04-20|1
 15|15 |2019-04-20|1    
 16|16 |2019-04-20|1
 17|17 |2019-04-20|1    
 18|18 |2019-04-20|1
 19|19 |2019-04-20|1    
 20|21 |2019-04-20|1
 21|22 |2019-04-20|1    
 22|23 |2019-04-20|1

这里有一个查询,我想它会给你你想要的结果。它使用分钟值的派生表,最小差值为10分钟的最近倍数。为了区分9和11,我们添加了
mn%10/10
,因此此查询的结果是(例如,对于分钟数=8,9,10,11,12):2.8,1.9,0,1.1,2.2。我们丢弃大于2的值,因为它们应该被忽略。然后将此派生表
连接到表中,以从相应行中选择数据:

SELECT d.*
FROM data d
JOIN (SELECT IF(hr = 23 AND mn = 59, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn = 59, (hr + 1) % 24, hr) AS hour,
             ((mn + 1) DIV 10) % 6 AS mn10, 
             MIN(LEAST(ABS(mn - mn DIV 10 * 10), ABS(mn - (mn + 9) DIV 10 * 10)) + (mn % 10 / 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff < 2) dd
  ON dd.date = IF(d.hr = 23 AND d.mn = 59, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn = 59, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 1) DIV 10) % 6
 AND dd.mndiff = LEAST(ABS(d.mn - d.mn DIV 10 * 10), ABS(d.mn - (d.mn + 9) DIV 10 * 10)) + (d.mn % 10 / 10)
更新

例如,如果第9分钟和第11分钟的数据可用(但第10分钟不可用),此查询将支持第11分钟的值。这可以通过改变

 + (mn % 10 / 10)
致:

如您所见,与
01
值相比,它更喜欢
59

仅选择在10分钟标记时或之前出现的值(例如,按优先顺序选择10,9,8,7),您可以将查询简化为:

SELECT d.*
FROM data d
JOIN (SELECT IF(hr = 23 AND mn >= 57, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn >= 57, (hr + 1) % 24, hr) AS hour,
             ((mn + 3) DIV 10) % 6 AS mn10, 
             MIN(ABS(mn - (mn + 9) DIV 10 * 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff <= 3) dd
  ON dd.date = IF(d.hr = 23 AND d.mn >= 57, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn >= 57, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 3) DIV 10) % 6
 AND dd.mndiff = ABS(mn - (mn + 9) DIV 10 * 10)

更新2

根据评论中的其他反馈,时间显示为最近10分钟标记的时间,而不是原始时间。这将导致对查询的微小更改:

SELECT dd.mn10 * 10 AS mn, dd.hour, dd.date, d.status, d.id
FROM data d
JOIN (SELECT IF(hr = 23 AND mn >= 57, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn >= 57, (hr + 1) % 24, hr) AS hour,
             ((mn + 3) DIV 10) % 6 AS mn10, 
             MIN(ABS(mn - (mn + 9) DIV 10 * 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff <= 3) dd
  ON dd.date = IF(d.hr = 23 AND d.mn >= 57, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn >= 57, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 3) DIV 10) % 6
 AND dd.mndiff = ABS(mn - (mn + 9) DIV 10 * 10)
 ORDER BY dd.date, dd.hour, mn

如果9、10和11都不可用怎么办?这是一种可能的情况吗?如果9、10、11不可用,那么它将被忽略。我只需要能够在之前或之后选择一个,这就是@nick。你能解释一下“mn”是什么吗?如果它是某个列表的外键,那么可以使用左连接和合并。如果这是一个平面文件,那就难多了。请确认一下,在
id=60
id=120
等地方。,
mn
将恢复到
1
并重新开始计数?是的,尼克,因为mn实际上是分钟,所以从59到00,然后到01等等@Nickthanks我生病了,这就是为什么你没有听到我的消息。这个查询将帮助很大,我会标记它。但尼克我注意到,这个问题在之后而不是之前最受欢迎。例如,如果9和11可用,它将首先选择11而不是9。但我认为可能会有一个解决办法。再说一次,如果我只考虑之前,而不考虑之后,那么如果10个id不可用,那么可以选择7、8、9个?@Donsplash很抱歉听到这个消息-希望你完全康复。我用两个新的查询更新了我的帖子:第一个将支持9值而不是11,第二个将只从之前(按照优先顺序为10、9、8、7)中进行选择,而不是在之后。Nick您的解决方案有效,谢谢,最后一个问题和帮助。谢谢你问我现在好多了。尼克,如果我选择7而不是10。我如何使其显示10作为mn字段,但将使用值7,在20的情况下,可能我使用19代替20,因为20不可用。我如何返回结果显示20,并根据情况使用值19。最后,如果我想容纳多达456789的数据,我可以将最后一个查询编辑为mn>=52。谢谢尼克的帮助。@Donsplash关于第一个问题,只需将
选择d.*
更改为
选择dd.mn10*10作为mn,d.hr,d.dt,d.status
。我不知道你说的第二个是什么意思?如果mn增加到一个大的数字,小时字段是什么样子的?你好,尼克,当我这样做时,如更改的选择d.*选择dd.mn10*10作为mn,d.hr,d.dt,d.status我在字段列表中得到一个错误无效列dd。我在第二个问题上的意思是,如果我可以在案例10中容纳值4、5、6、7、8、9,或者任何其他更接近的值,则不可用,谢谢您的帮助。
HAVING mndiff < 2
HAVING mndiff < 1
SELECT d.*, dd.*
FROM data d
JOIN (SELECT IF(hr = 23 AND mn = 59, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn = 59, (hr + 1) % 24, hr) AS hour,
             ((mn + 1) DIV 10) % 6 AS mn10, 
             MIN(LEAST(ABS(mn - mn DIV 10 * 10), ABS(mn - (mn + 9) DIV 10 * 10)) - (mn % 10 / 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff < 1) dd
  ON dd.date = IF(d.hr = 23 AND d.mn = 59, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn = 59, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 1) DIV 10) % 6
 AND dd.mndiff = LEAST(ABS(d.mn - d.mn DIV 10 * 10), ABS(d.mn - (d.mn + 9) DIV 10 * 10)) - (d.mn % 10 / 10)
id  mn  hr  dt          status
2   50  23  2019-04-19  1
11  59  23  2019-04-19  1
20  11  0   2019-04-20  1
27  19  0   2019-04-20  1
SELECT d.*
FROM data d
JOIN (SELECT IF(hr = 23 AND mn >= 57, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn >= 57, (hr + 1) % 24, hr) AS hour,
             ((mn + 3) DIV 10) % 6 AS mn10, 
             MIN(ABS(mn - (mn + 9) DIV 10 * 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff <= 3) dd
  ON dd.date = IF(d.hr = 23 AND d.mn >= 57, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn >= 57, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 3) DIV 10) % 6
 AND dd.mndiff = ABS(mn - (mn + 9) DIV 10 * 10)
id  mn  hr  dt          status
2   50  23  2019-04-19  1
11  59  23  2019-04-19  1
19  8   0   2019-04-20  1
27  19  0   2019-04-20  1
33  27  0   2019-04-20  1
SELECT dd.mn10 * 10 AS mn, dd.hour, dd.date, d.status, d.id
FROM data d
JOIN (SELECT IF(hr = 23 AND mn >= 57, dt + INTERVAL 1 DAY, dt) AS date,
             IF(mn >= 57, (hr + 1) % 24, hr) AS hour,
             ((mn + 3) DIV 10) % 6 AS mn10, 
             MIN(ABS(mn - (mn + 9) DIV 10 * 10)) AS mndiff
      FROM data
      GROUP BY date, hour, mn10
      HAVING mndiff <= 3) dd
  ON dd.date = IF(d.hr = 23 AND d.mn >= 57, d.dt + INTERVAL 1 DAY, d.dt)
 AND dd.hour = IF(d.mn >= 57, (d.hr + 1) % 24, d.hr)
 AND dd.mn10 = ((d.mn + 3) DIV 10) % 6
 AND dd.mndiff = ABS(mn - (mn + 9) DIV 10 * 10)
 ORDER BY dd.date, dd.hour, mn
mn  hour    date        status  id
0   23      2019-04-19  1       12
50  23      2019-04-19  1       2
0   0       2019-04-20  1       11
10  0       2019-04-20  1       20
20  0       2019-04-20  1       28
30  0       2019-04-20  1       34