我在这个问题上一直在撕扯我的头发。我正在使用现有数据集,需要从表A中的列中删除所有空值并将它们分流,以便按照表B中的顺序排序
我需要的东西相当于Coalesce,但要检索第n个值,这样我就可以像在表B中那样对结果进行排序
我有什么:
表A
Name CURRENT OCT12 SEPT12 AUG12 JUL12 JUN12 MAY12 APR12
---------------------------------------------------------
A NULL NULL Aug-12 NULL NULL Jun-12 NULL Apr-12
B Nov-12 NULL Aug-12 NULL Jul-12Jun-12 NULL Apr-12
我需要什么:
表B
Name Change1 Change2 Change3 Change4 Change5 Change6
----------------------------------------------------
A Aug-12 Jun-12 Apr-12 NULL NULL NULL
B Nov-12 Aug-12 Jul-12 Jun-12 Apr-12 NULL
代码方面,它将类似于:
Select
first non-null value as Change1
,second non-null value as Change2
,third non-null value as Change3
,fourth non-null value as Change4
,fifth non-null value as Change5...etc..
from Table_A
我正在使用MySQL,我不知道如何引用第n个非null值以便将它们调用到Table_B中
有没有人有任何想法?
答案 0 :(得分:0)
我不确定是否会推荐使用此解决方案...数据的规范化始终是更好的选择,但我想使用普通的SQL来回答一些字符串函数。此查询应返回您要查找的内容:
SELECT
Name,
Changes,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 1)), ',', 1)) as Change1,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 2)), ',', 1)) as Change2,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 3)), ',', 1)) as Change3,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 4)), ',', 1)) as Change4,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 5)), ',', 1)) as Change5,
REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING_INDEX(Changes, ',', 6)), ',', 1)) as Change6
FROM (
SELECT
Name,
CONCAT_WS(',', CURRENT, OCT12, SEPT12, AUG12, JUL12, JUN12, MAY12, APR12, ',') as Changes
FROM
TableA
) s
我在逗号分隔的字符串中连接所有值,在字符串的末尾有两个逗号(无论如何,一个逗号就足够了,但是更容易放两个,只是忽略最后一个......),因为我正在使用CONCAT_WS,它会自动跳过空值,结果字符串将类似于Aug-12,Jun-12,Apr-12,,
。
然后在外部查询中,我使用SUBSTRIG_INDEX提取字符串的第n个元素。我建议对数据库进行规范化,但如果你需要快速修复,这个解决方案可能是一个很好的起点。
看到它正常工作here。
请注意,我没有返回没有更改的NULL值,但我返回的是空字符串。如果需要,可以更改。
答案 1 :(得分:0)
如果您不想使用字符串函数,则可以使用unpivot和行号分区来尝试使用此sql:
CREATE TABLE #TableA
(
"Name" VARCHAR(10),
"CURRENT" VARCHAR(10),
OCT12 VARCHAR(10),
SEPT12 VARCHAR(10),
AUG12 VARCHAR(10),
JUL12 VARCHAR(10),
JUN12 VARCHAR(10),
MAY12 VARCHAR(10),
APR12 VARCHAR(10)
)
INSERT INTO #TableA
("Name", "CURRENT", OCT12, SEPT12, AUG12, JUL12, JUN12, MAY12, APR12)
VALUES
('A', NULL, NULL, 'Aug-12', NULL, NULL, 'Jun-12', NULL, 'Apr-12'),
('B', 'Nov-12', NULL, 'Aug-12', NULL, 'Jul-12', 'Jun-12', NULL, 'Apr-12')
SELECT * FROM #TableA;
Select "Name",
Min(Case row_num When 1 Then data End) Change1,
Min(Case row_num When 2 Then data End) Change2,
Min(Case row_num When 3 Then data End) Change3,
Min(Case row_num When 4 Then data End) Change4,
Min(Case row_num When 5 Then data End) Change5,
Min(Case row_num When 6 Then data End) Change6
From
(
select "Name",data,DBColumnName,
ROW_NUMBER() OVER (PARTITION BY "Name" ORDER BY "Name") row_num
From #TableA
unpivot (data for DBColumnName in ("CURRENT",OCT12,SEPT12,AUG12,JUL12,JUN12,MAY12,APR12) ) as z
) TableB
group by "Name";
参考:
-TSQL Pivot without aggregate function
-https://www.sqlservertutorial.net/sql-server-window-functions/sql-server-row_number-function/