【问题标题】:TQSL to reformat records with duplicate data into one record [closed]TQSL 将具有重复数据的记录重新格式化为一条记录 [关闭]
【发布时间】:2017-08-31 05:53:23
【问题描述】:

我们正在向我们提供一个表格,其中行中有大量重复数据,唯一的区别是一周中某一天的开盘和关盘时间 - 数据以这种方式提供,客户将不要从头再来。

 Col1 Col2   Col3   Col4   Col5   Col6    Col7
 1    Shop1  Mon    open   6am    Close   4pm
 2    Shop1  Tue    Open   6am    Close   5pm
 3    shop1  Wed    Open   6am    Close   4pm
 4    Shop2  Mon    open   10am   Close   3pm
 5    Shop2  Tue    open   11am   Close   2pm

如何使用 TSQL 以下列方式存储/呈现信息,以便我可以从表或最好从视图中检索数据 - 所以我不必通过例如运行数据。一个PHP程序为我做格式化?我处理的数据可以采用我们可以直接从理想的表/视图中读取的格式/

 Col1 Col2  Col3 Col4  Col5  Col6   Col7  col8  col9  col10 Col11 Col12    
 1    Shop1 Mon  open  6am   Close  4pm   Tue   Open  6am   Close 5pm
 2    Shop2 Mon  open  10am  close  4pm   Tue   open  11am  close 2pm

我确切地知道打开关闭时间需要多少列,即一周中的每一天需要 5 列,因此创建表来存储信息不是问题,也不会改变

亲切的问候 泷

【问题讨论】:

  • 你应该保持这个标准化,而不是你想要做的格式。并且不需要具有“打开”和“关闭”值的列。这可以很容易地浓缩为 Shop、OperationDay、OpenTime、CloseTime。您不需要 12 列。
  • Col 是否会延长至天数?前任。 Shop1 有星期三,应该是从 Col13 到 Col17 吗?
  • 您好,您是正确的,我不需要打开和关闭列。我处理新表应该只有shop1,day1,opentime,closetime,day2,opentime,closetime,......这可以使用TSQL来完成吗?请注意,原始数据由第三方提供,他们不会更改他们提供的数据。我们必须在最后重新格式化它,因此我的问题。干杯!

标签: sql sql-server


【解决方案1】:

这应该是你要找的……

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    Col2 CHAR(5) NOT NULL,
    Col3 CHAR(3) NOT NULL,
    Col4 CHAR(4) NOT NULL,
    Col5 TIME(0) NOT NULL,
    Col6 CHAR(5) NOT NULL,
    Col7 TIME(0) NOT NULL 
    );

INSERT #TestData (Col2, Col3, Col4, Col5, Col6, Col7) VALUES 
    ('Shop1', 'Mon', 'open', '6am ', 'Close', '4pm'),
    ('Shop1', 'Tue', 'Open', '6am ', 'Close', '5pm'),
    ('shop1', 'Wed', 'Open', '6am ', 'Close', '4pm'),
    ('Shop2', 'Mon', 'open', '10am', 'Close', '3pm'),
    ('Shop2', 'Tue', 'open', '11am', 'Close', '2pm');


-- SELECT * FROM #TestData td;'
--============================================================

SELECT 
    Col1 = ROW_NUMBER() OVER (ORDER BY td.Col2),
    td.Col2,
    Col3 = MAX(CASE WHEN dn.DayNum = 1 THEN td.Col3 END),
    Col4 = MAX(CASE WHEN dn.DayNum = 1 THEN 'open' END),
    Col5 = MAX(CASE WHEN dn.DayNum = 1 THEN col5 END),
    Col6 = MAX(CASE WHEN dn.DayNum = 1 THEN 'close' END),
    Col7 = MAX(CASE WHEN dn.DayNum = 1 THEN col7 END),

    Col8 = MAX(CASE WHEN dn.DayNum = 2 THEN td.Col3 END),
    Col9 = MAX(CASE WHEN dn.DayNum = 2 THEN 'open' END),
    Col10 = MAX(CASE WHEN dn.DayNum = 2 THEN col5 END),
    Col11 = MAX(CASE WHEN dn.DayNum = 2 THEN 'close' END),
    Col12 = MAX(CASE WHEN dn.DayNum = 2 THEN col7 END),

    Col13 = MAX(CASE WHEN dn.DayNum = 3 THEN td.Col3 END),
    Col14 = MAX(CASE WHEN dn.DayNum = 3 THEN 'open' END),
    Col15 = MAX(CASE WHEN dn.DayNum = 3 THEN col5 END),
    Col16 = MAX(CASE WHEN dn.DayNum = 3 THEN 'close' END),
    Col17 = MAX(CASE WHEN dn.DayNum = 3 THEN col7 END),

    Col18 = MAX(CASE WHEN dn.DayNum = 4 THEN td.Col3 END),
    Col19 = MAX(CASE WHEN dn.DayNum = 4 THEN 'open' END),
    Col20 = MAX(CASE WHEN dn.DayNum = 4 THEN col5 END),
    Col21 = MAX(CASE WHEN dn.DayNum = 4 THEN 'close' END),
    Col22 = MAX(CASE WHEN dn.DayNum = 4 THEN col7 END),

    Col23 = MAX(CASE WHEN dn.DayNum = 5 THEN td.Col3 END),
    Col24 = MAX(CASE WHEN dn.DayNum = 5 THEN 'open' END),
    Col25 = MAX(CASE WHEN dn.DayNum = 5 THEN col5 END),
    Col26 = MAX(CASE WHEN dn.DayNum = 5 THEN 'close' END),
    Col27 = MAX(CASE WHEN dn.DayNum = 5 THEN col7 END)
FROM 
    #TestData td
    CROSS APPLY ( VALUES (CASE td.Col3
                                WHEN 'Mon' THEN 1
                                WHEN 'Tue' THEN 2
                                WHEN 'Wed' THEN 3
                                WHEN 'Thu' THEN 4
                                WHEN 'Fri' THEN 5
                            END) ) dn (DayNum)
GROUP BY
    td.Col2;

结果...

Col1                 Col2  Col3 Col4 Col5             Col6  Col7             Col8 Col9 Col10            Col11 Col12            Col13 Col14 Col15            Col16 Col17            Col18 Col19 Col20            Col21 Col22            Col23 Col24 Col25            Col26 Col27
-------------------- ----- ---- ---- ---------------- ----- ---------------- ---- ---- ---------------- ----- ---------------- ----- ----- ---------------- ----- ---------------- ----- ----- ---------------- ----- ---------------- ----- ----- ---------------- ----- ----------------
1                    Shop1 Mon  open 06:00:00         close 16:00:00         Tue  open 06:00:00         close 17:00:00         Wed   open  06:00:00         close 16:00:00         NULL  NULL  NULL             NULL  NULL             NULL  NULL  NULL             NULL  NULL
2                    Shop2 Mon  open 10:00:00         close 15:00:00         Tue  open 11:00:00         close 14:00:00         NULL  NULL  NULL             NULL  NULL             NULL  NULL  NULL             NULL  NULL             NULL  NULL  NULL             NULL  NULL

【讨论】:

  • 谢谢杰森。我试过你的方法,效果很好。多谢了。干杯!克里斯
  • 太棒了!很高兴我能帮上忙。并感谢您的良好反馈。 :)
【解决方案2】:

此查询效率不高,我不建议直接从 SQL 查询中将其置于此格式,但假设您的数据继续遵循您在上面发布的相同格式,则应该可以执行以下操作。

SELECT DISTINCT
    Col1,
    Col2,
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Mon'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Mon'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Mon'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Mon'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Mon'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Tue'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Tue'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Tue'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Tue'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Tue'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Wed'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Wed'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Wed'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Wed'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Wed'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Thur'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Thur'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Thur'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Thur'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Thur'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Fri'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Fri'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Fri'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Fri'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Fri'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sat'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sat'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sat'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sat'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sat'),
    (SELECT TOP 1 Col3 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sun'),
    (SELECT TOP 1 Col4 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sun'),
    (SELECT TOP 1 Col5 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sun'),
    (SELECT TOP 1 Col6 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sun'),
    (SELECT TOP 1 Col7 FROM ShopTable st_inner WHERE st_inner.Col1 = st.Col1 AND st_inner.Col3 = 'Sun')

【讨论】:

  • 感谢卡尔。我使用您的示例编写了 SQL,是的,它确实有效。我的 SQL 不是最好的,你的例子帮助我更多地理解 SQL。在决定最终解决方案之前,我还将查看下面的其他回复。多谢了。干杯!
【解决方案3】:

我没有办法测试这个查询,但基本上你需要这样的东西:

SELECT mon.col2, MonStart, MonEnd, TueStart, ... 
FROM 
(
    SELECT distinct Col2,
    CASE col3 WHEN 'Mon' THEN Col5 ELSE NULL END as MonStart,
    CASE col3 WHEN 'Mon' THEN Col7 ELSE NULL END as MonEnd,
    FROM table
) mon
INNER JOIN 
(
    SELECT distinct Col2,
    CASE col3 WHEN 'Tue' THEN Col5 ELSE NULL END as TueStart,
    CASE col3 WHEN 'Tue' THEN Col7 ELSE NULL END as TueEnd,
    FROM table
) tue on mon.col2 = tue.col2
INNR JOIN 
...

就像在 cmets 中提到的那样,您不需要额外的列来显示打开/关闭状态,只需为您的列提供正确的名称。

【讨论】:

  • 谢谢拉马尔。我也会尝试你的方法,但是我选择了 Jason 的解决方案。感谢您的时间和精力
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2017-10-20
  • 2015-12-29
  • 2011-08-18
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
相关资源
最近更新 更多