Выборка для базы данных SQL - PullRequest
2 голосов
/ 03 октября 2019

У меня есть столбец «стейк», представляющий количество стейков в фунтах, которые моя фирма купила с 1-го дня 2010 года. У меня есть еще один столбец «c_steak», представляющий кумулятивную сумму фунтов стейков.

╔═══╦════════════╦═════════════╗
║   ║ steak      ║ c_steak     ║
╠═══╬════════════╬═════════════╣
║ 1 ║ 0.2        ║ 0.2         ║
║ 2 ║ 0.2        ║ 0.4         ║
║ 3 ║ 0.3        ║ 0.7         ║
╚═══╩════════════╩═════════════╝

Как мне сделать выборку из таблицы, чтобы взять ряд, как только мы купим еще 100 фунтов стейка? (образец ОДНОЙ строки сразу после того, как c_steak достигает 100, 200, 300, 400 и т. д.).

Примечание (РЕДАКТИРОВАТЬ):

  1. c_steak is float. Он может точно не набрать 100, 200, 300 ....

  2. Если c_steak имеет вид ..., 99.5, 105.3, 107.1, ... тогда строка, соответствующая 105.3, будетбыть отобранным.

  3. если c_steak имеет вид ..., 99, 100.1, 100.2, 100.3, 105 ..., тогда будет выбрана строка, соответствующая 100.1.

Ответы [ 4 ]

2 голосов
/ 03 октября 2019

Почти наверняка вам нужен LAG метод. Вы можете попробовать так:

SELECT *
FROM (
    SELECT c_steak
        ,lag(c_steak, 1, 0) OVER (ORDER BY id) lg
     FROM myTable
    ) sub
WHERE cast(sub.c_steak as int) %100 - cast(sub.lg as int)% 100 < 0

Логика такова, что при достижении суммы 100, 200 и т. Д. Разница в модуле с предыдущим значением должна быть отрицательной. например:

80%100 = 80 where as 101%100 = 1
195%100 = 95 where as 205%100 = 5
293%100 = 93 where as 320%100 = 20
etc
1 голос
/ 03 октября 2019

Это работает:

   SELECT m2.id,m2.steak,m2.c_steak FROM t1 as m1 inner join t1 as m2 on m2.id = m1.id + 1 WHERE cast(m2.c_steak as int) % 100 < cast(m1.c_steak as int) % 100;

Смотрите здесь:

ДЕМО

===========

РЕДАКТИРОВАТЬ (в случае пропуска столбца id вообще):

   SELECT distinct m2.id,m2.steak,m2.c_steak FROM t1 as m1 inner join t1 as m2 on m2.id > m1.id WHERE cast(m2.c_steak as int) % 100 < cast(m1.c_steak as int) % 100;

DEMO

===========

0 голосов
/ 06 октября 2019

Вы могли бы предоставить некоторые образцы данных.

Делаете это сейчас:

WITH    
-- sample data , this will be in the table                                                                    
input(id,steak_sold) AS (
          SELECT  1,30.07  
UNION ALL SELECT  2,30.01 
UNION ALL SELECT  3,30.02 
UNION ALL SELECT  4,30.03 
UNION ALL SELECT  5,30.04 
UNION ALL SELECT  6,30.05 
UNION ALL SELECT  7,30.06 
UNION ALL SELECT  8,30.07 
UNION ALL SELECT  9,30.08 
UNION ALL SELECT 10,30.09 
UNION ALL SELECT 11,30.10
UNION ALL SELECT 12,30.11
UNION ALL SELECT 13,30.12
UNION ALL SELECT 14,30.13
UNION ALL SELECT 15,30.14
UNION ALL SELECT 16,30.15
UNION ALL SELECT 17,30.16
)
-- real WITH clause would begin here: creating running sum myself ....
,
runsum AS (
SELECT
  *
, SUM(steak_sold) OVER(ORDER BY id) AS c_steak
FROM input
)
SELECT 
  *
FROM runsum
-- this running sum is above a certain 100 
-- previous (running sum - steak_sold) below that 100
-- integer division by 100 of the two differs
WHERE c_steak//100 <> (c_steak - steak_sold) //100;
-- out  id | steak_sold | c_steak 
-- out ----+------------+---------
-- out   4 |      30.03 |  120.13
-- out   7 |      30.06 |  210.28
-- out  10 |      30.09 |  300.52
-- out  14 |      30.13 |  420.98
-- out  17 |      30.16 |  511.43
-- out (5 rows)
-- out 
-- out Time: First fetch (5 rows): 53.018 ms. All rows formatted: 53.066 ms
0 голосов
/ 03 октября 2019

Вы можете использовать функцию MOD (). Документы: https://dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html#function_mod

SELECT * FROM Table WHERE MOD(c_steak, 100) = 0;

РЕДАКТИРОВАТЬ: В ответ на редактирование OP, вы можете использовать FLOOR () на c_steak, чтобы получить int. Документы: https://dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html#function_floor

SELECT * FROM Table WHERE MOD(FLOOR(c_steak), 100) = 0;
...