SQL中的多行单行

问题描述 投票:0回答:5

大家好我有这个表,我希望按客户ID显示单行组中的结果,并显示库存1和2的可用性。

这是我的桌子

id      client  stock   material    quantity    availability    date    
62      56      1       0           0           100             2017-12-16 23:55:01 
63      56      2       0           0           900             2017-12-16 23:55:01 
64      56      1       100         -20         80              2017-12-16 23:55:20 
65      56      1       80          100         180             2017-12-16 23:56:06 
66      56      1       180         200         380             2017-12-16 23:56:21 
67      56      1       380         500         880             2017-12-16 23:58:11 
68      56      1       880         -580        300             2017-12-16 23:58:38 
69      56      2       900         -90         810             2017-12-17 23:59:18 

我想要的结果是从上次日期得到结果,按客户ID分组,并将股票1和股票2合并为单行

client  availability1   availability2
56      300             810

我试试这个查询

SELECT
    historys.id
    ,(CASE WHEN historys.stock = 1 THEN availability END) AS availability1
    ,(CASE WHEN historys.stock = 2 THEN availability END) AS availability2
FROM historys
GROUP BY historys.client
ORDER by historys.id

结果是

id  availability1   availability2 
56  NULL            810

如果有人帮助我,我将不胜感激。谢谢。

php mysql sql
5个回答
4
投票

您需要在聚合之前过滤到正确的行。这是一种方法:

SELECT h.client,
       MAX(CASE WHEN h.stock = 1 THEN h.availability END) AS availability1
       MAX(CASE WHEN h.stock = 2 THEN h.availability END) AS availability2
FROM historys h
WHERE h.date = (SELECT MAX(h2.date) FROM historys h2 WHERE h2.stock = h.stock)
GROUP BY h.client

1
投票

使用工会

SELECT 
client, max(availability1) AS availability1, max(availability2) AS availability2
FROM 
(
SELECT
client
 ,availability AS availability1
 ,0 AS availability2
FROM historys hist
WHERE id = (select max(id) from historys where client = hist.client and stock = 1)
    UNION ALL
SELECT
client
 ,0 AS availability1
 ,availability AS availability2
FROM historys hist2
WHERE id = (select max(id) from historys where client = hist2.client and stock = 2)
) a
GROUP by client
ORDER by client

1
投票

您拥有的NULL是因为您从历史记录行中选择的数据不能同时包含stock = 1和stock = 2的可用性。

您可以像上面那样使用历史记录绕过它:

在子请求中(作为d),我们通过客户端获得最大日期,然后我们连接历史记录两次以获得连续可用性。

select d.client,
       h1.availability availability1,
       h2.availability availability2
from
(
  select client,
         max(case when stock = 1 then date end) d1,
         max(case when stock = 2 then date end) d2
  from historys
  group by client
) d
join historys h1 on (h1.stock = 1
                     and h1.date = d.d1
                     and h1.client = d.client)
join historys h2 on (h2.stock = 2
                     and h2.date = d.d2
                     and h2.client = d.client)

你可以在这里找到一个SQLFiddle:http://sqlfiddle.com/#!9/d1ea4/5

谢谢


1
投票

这可能对您有所帮助:

 SELECT T.client client ,
    SUM(CASE WHEN T.Stock = 1 THEN T.availability
        END) availability1 ,
    SUM(CASE WHEN T.Stock = 2 THEN T.availability
        END) availability2
 FROM   historys T
    INNER JOIN ( SELECT MAX(date) Max_Date ,
                        stock
                 FROM   historys
                 GROUP BY stock
               ) T1 ON T1.Max_Date = T.date
                       AND T1.stock = T.stock
  GROUP BY T.client

0
投票

根据您的MySQL版本,您应该能够使用窗口函数和公用表表达式执行此操作:

-- Build derived src table with "latest date" rows
WITH src AS (
    SELECT id, client, stock, material, quantity, availability, date
    FROM (
        SELECT 
            id, client, stock, material, quantity, availability, date,
            ROW_NUMBER() OVER(PARTITION BY client, stock ORDER BY date DESC) ClientStockRank -- For each (client, stock) pair, rank each row by date
        FROM historys a
    ) src
    WHERE ClientStockRank = 1 -- Only get rows with "latest date"
)
SELECT 
    client,
    MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) END AS Availability1, -- Get "max" value for "stock 1"
    MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) END AS Availability2 -- Get "max" value for "stock 2"
FROM src
GROUP BY client

我认为你需要MySQL 8+。如果没有,还应该有其他方法来做到这一点。如果有效,请告诉我。

更新 实际上,这也应该足够了:

SELECT DISTINCT
    client,
    MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS Availability1,
    MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS availability2
FROM historys
© www.soinside.com 2019 - 2024. All rights reserved.