我已经有了这张表,我需要用最后一个A,第一个B,然后最后一个B和第一个A生成一行。预期结果在这里:
ID | Date | OPS
6 | 2018-12-20 | A
7 | 2018-12-20 | B
11 | 2018-12-24 | B
12 | 2018-12-25 | A
我尝试用零运气处理以下代码。 我无法使用分析功能,例如ROW_NUMBER(),LEAD()或LAG()。
SELECT *
FROM T1
JOIN (
SELECT COUNT(*) cnt, t1.OPS
FROM (
SELECT DISTINCT ts1.OPS
FROM T1 ts1
JOIN T1 tx1 ON ts1.OPS = tx1.OPS
) t1
JOIN (
SELECT DISTINCT ts2.OPS
FROM T1 ts2
JOIN T1 tx2 ON ts2.OPS = tx2.OPS
) t2 on t1.OPS <= t2.OPS
GROUP BY t1.OPS
) tt ON T1.OPS = tt.OPS
我的桌子是:
CREATE TABLE t1(
ID int,
Date1 date,
OPS CHAR
);
INSERT INTO T1 VALUES
( 1, '2018-12-17', 'A'),
( 2, '2018-12-18', 'A'),
( 3, '2018-12-19', 'A'),
( 4, '2018-12-19', 'A'),
( 5, '2018-12-19', 'A'),
( 6, '2018-12-20', 'A'),
( 7, '2018-12-20', 'B'),
( 8, '2018-12-21', 'B'),
( 9, '2018-12-22', 'B'),
(10, '2018-12-23', 'B'),
(11, '2018-12-24', 'B'),
(12, '2018-12-25', 'A'),
(13, '2018-12-26', 'A'),
(14, '2018-12-27', 'A'),
(15, '2018-12-28', 'A');
答案 0 :(得分:1)
如果没有LEAD
和LAG
,并且考虑到每个日期有多个记录,则可以使用可怕的简化解决方案,它假定记录是按以下顺序排序的id
,而不是日期。它不需要id连续,并且可以用于两个以上的ops值:
SELECT *
FROM t AS ref
WHERE EXISTS (
SELECT 1
FROM t AS lag
WHERE ops <> ref.ops
AND id < ref.id
AND NOT EXISTS (
SELECT 1
FROM t AS tmp
WHERE id > lag.ID
AND id < ref.id
)
) OR EXISTS (
SELECT 1
FROM t AS led
WHERE ops <> ref.ops
AND id > ref.id
AND NOT EXISTS (
SELECT 1
FROM t AS tmp
WHERE id < led.ID
AND id > ref.id
)
)
基本上,对于每一行,查询都会搜索ID不匹配的所有先前行,然后确定它们之间是否存在一行。它也向前搜索。
答案 1 :(得分:0)
尝试以下逻辑,该逻辑使用一系列并集来表达您的问题:
(SELECT ID, Date1, OPS FROM T1 WHERE OPS = 'B' ORDER BY Date1 LIMIT 1)
UNION ALL
(SELECT ID, Date1, OPS FROM T1
WHERE OPS = 'A' AND Date1 <= (SELECT MIN(Date1) FROM T1 WHERE OPS = 'B')
ORDER BY Date1 DESC LIMIT 1)
UNION ALL
(SELECT ID, Date1, OPS FROM T1 WHERE OPS = 'B' ORDER BY Date1 DESC LIMIT 1)
UNION ALL
(SELECT ID, Date1, OPS FROM T1
WHERE OPS = 'A' AND Date1 >= (SELECT MAX(Date1) FROM T1 WHERE OPS = 'B')
ORDER BY Date1 LIMIT 1)
ORDER BY Date1, OPS;
通常请注意,这是一个空白和孤岛的问题。如果不使用您似乎没有的分析功能,这些操作将很难处理。如果您使用的是MySQL 8+,那么我们可以用一个简洁得多的查询来表述。
答案 2 :(得分:0)
您可以使用相关子查询来计算每个操作的最小和最大ID,例如
SELECT t.*
FROM T1 t
WHERE
t.id IN (
SELECT MIN(id) FROM T1 WHERE ops = t.ops
UNION ALL SELECT MAX(id) FROM T1 WHERE ops = t.ops
)
ORDER BY t.ops, t.id DESC
答案 3 :(得分:0)
如果我们允许使用max和min函数,那么很容易分别计算这4个结果并合并各个结果。
-选择最后一个A 选择ID,Date1,OPS 从test_t1 其中test_t1.OPS ='A' 和test_t1.Date1在 ( 选择max(t1_a.Date1)作为Date1 从 (选择ID,Date1,OPS 从test_t1 其中OPS ='A')t1_a内部联接 (选择min(Date1)作为Date1 从test_t1 其中OPS ='B')t1_min_b 在t1_a.Date1 <= t1_min_b.Date1上 ) 联合
-选择第一个B
选择ID,Date1,OPS 从test_t1 其中test_t1.OPS ='B' 和test_t1.Date1在 ( 选择min(Date1)作为Date1 从test_t1 其中OPS ='B' ) 联盟 / * 选择最后一个B / 选择ID,Date1,OPS 从test_t1 其中test_t1.OPS ='B' 和test_t1.Date1在 ( 选择max(Date1)作为Date1 从test_t1 其中OPS ='B' ) 联盟 / 选择第一个A * / 选择ID,Date1,OPS 从test_t1 其中test_t1.OPS ='A' 和test_t1.Date1在 ( 选择min(t1_a.Date1)作为Date1 从 (选择ID,Date1,OPS 从test_t1 其中OPS ='A')t1_a内部联接 (选择max(Date1)作为Date1 从test_t1 其中OPS ='B')t1_max_b 在t1_a.Date1> = t1_max_b.Date1上 ) ;