【问题标题】:Pivoting a table with multiple columns in SQL在 SQL 中透视具有多列的表
【发布时间】:2020-04-15 18:56:43
【问题描述】:

我的目标是获取两个对应商店编号的列表,并提供类似于以下内容的输出:

最终目标:根据每个 zip9 的 2 行的源数据,按行程时间和距离生成最近商店的列表,其中每行是到相关商店的行程时间和时间。

结果是每个邮政编码有 2 个商店可供选择,并且要求能够同时返回一行并包含两个选项。

+-----------+---------------+---------------------+-------------------+-------------------------+
|    zip    | Shortest_time | Shortest_time_store | Shortest_distance | Shortest_distance_store |
+-----------+---------------+---------------------+-------------------+-------------------------+
|  70011134 | 38.7035       |                  75 | 21.3124           |                     115 |
|  70011186 | 38.4841       |                  75 | 21.4144           |                     115 |
|  70011207 | 39.1567       |                  75 | 21.1826           |                     115 |
| 100013232 | 22.976        |                 145 | 9.5031            |                     115 |
| 112075140 | 21.888        |                 145 | 7.3705            |                     115 |
+-----------+---------------+---------------------+-------------------+-------------------------+

原始数据集

+---------------+--------------------------+-----------------------+------------------+
| CORRECTED_ZIP | SourceOrganizationNumber | Travel Time (Minutes) | Distance (Miles) |
+---------------+--------------------------+-----------------------+------------------+
|      70011134 |                       75 | 38.7035               | 26.8628          |
|      70011134 |                      115 | 39.3969               | 21.3124          |
|      70011186 |                       75 | 38.4841               | 26.7609          |
|      70011186 |                      115 | 39.6389               | 21.4144          |
|      70011207 |                       75 | 39.1567               | 31.2771          |
|      70011207 |                      115 | 39.188                | 21.1826          |
|     100013232 |                      115 | 28.6561               | 9.50311          |
|     100013232 |                      145 | 22.976                | 10.0307          |
|     112075140 |                      115 | 36.1803               | 7.37053          |
|     112075140 |                      145 | 21.888                | 9.50123          |
+---------------+--------------------------+-----------------------+------------------+

使用此查询修改后的数据集:

SELECT TOP 1000 [corrected_zip]
              , TRY_CONVERT( DECIMAL(18, 4), ROUND([Travel Time (Minutes)], 4)) AS [Unit of Measurement]
              , [SourceOrganizationNumber]
              , 'Time' AS                                                          [Type]
FROM                       [db].[dbo].[my_table_A] [tt]
WHERE                     [tt].[CORRECTED_ZIP] IN('070011134', '070011186', '070011207', '112075140', '100013232')
AND [Travel Time (Minutes)] IN
(
    SELECT MIN([Travel Time (Minutes)])
    FROM   [db].[dbo].[my_table_A]
    WHERE  [CORRECTED_ZIP] = [tt].[CORRECTED_ZIP]
    GROUP BY [CORRECTED_ZIP]
)
UNION ALL
SELECT TOP 1000 [corrected_zip]
              , TRY_CONVERT( DECIMAL(18, 4), ROUND([Distance (Miles)], 4))
              , [SourceOrganizationNumber]
              , 'Distance'
FROM            [db].[dbo].[my_table_A] [tt]
WHERE           [tt].[CORRECTED_ZIP] IN('070011134', '070011186', '070011207', '112075140', '100013232')
AND [Distance (Miles)] IN
(
    SELECT MIN([Distance (Miles)])
    FROM   [db].[dbo].[my_table_A]
    WHERE  [CORRECTED_ZIP] = [tt].[CORRECTED_ZIP]
    GROUP BY [CORRECTED_ZIP]
)
ORDER BY [CORRECTED_ZIP];
+---------------+---------------------+--------------------------+----------+
| corrected_zip | Unit of Measurement | SourceOrganizationNumber |   Type   |
+---------------+---------------------+--------------------------+----------+
|      70011134 | 38.7035             |                       75 | Time     |
|      70011134 | 21.3124             |                      115 | Distance |
|      70011186 | 21.4144             |                      115 | Distance |
|      70011186 | 38.4841             |                       75 | Time     |
|      70011207 | 39.1567             |                       75 | Time     |
|      70011207 | 21.1826             |                      115 | Distance |
|     100013232 | 9.5031              |                      115 | Distance |
|     100013232 | 22.976              |                      145 | Time     |
|     112075140 | 21.888              |                      145 | Time     |
|     112075140 | 7.3705              |                      115 | Distance |
+---------------+---------------------+--------------------------+----------+

尝试旋转后的数据

+---------------+--------------------------+----------+---------+
| corrected_zip | SourceOrganizationNumber | Distance |  Time   |
+---------------+--------------------------+----------+---------+
|     070011134 |                      115 | 21.3124  | NULL    |
|     070011134 |                       75 | NULL     | 38.7035 |
|     070011186 |                      115 | 21.4144  | NULL    |
|     070011186 |                       75 | NULL     | 38.4841 |
|     070011207 |                      115 | 21.1826  | NULL    |
|     070011207 |                       75 | NULL     | 39.1567 |
|     100013232 |                      115 | 9.5031   | NULL    |
|     100013232 |                      145 | NULL     | 22.9760 |
|     112075140 |                      115 | 7.3705   | NULL    |
|     112075140 |                      145 | NULL     | 21.8880 |
+---------------+--------------------------+----------+---------+

似乎我的问题是选择正确的商店 ID,而不是按商店 ID 分组?

【问题讨论】:

    标签: sql-server database tsql group-by pivot


    【解决方案1】:

    你可以在子查询中使用row_number()两次(一次按时间排序,一次按距离排序),然后在外部查询中进行条件聚合:

    select
        corrected_zip,
        min(travel_time) shortest_time,
        min(case when rnt = 1 then source_organization_number end) shortest_time_store,
        min(distance) shortest_distance,
        min(case when rnd = 1 then source_organization_number end) shortest_distance_store
    from (
        select 
            t.*,
            row_number() over(partition by corrected_zip order by travel_time) rnt,
            row_number() over(partition by corrected_zip order by distance) rnd
        from mytable t
    ) t
    group by corrected_zip
    

    【讨论】:

    • 一旦我最终决定发帖,答案总是那么简单。我不敢相信我忘记了我可以同时运行多个窗口函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2011-12-14
    相关资源
    最近更新 更多