我有一个名为“FPB”的三栏价格表,如下所示:
[Part Number] [Quantity] [Price]
AAA-AAAA 100 1.23
AAA-AAAA 200 1.15
BBB-BBBB 100 5.60
CCC-CCCC 500 3.21
....
每个零件编号在多行中有多个条目。
我正在尝试重新组织表格,看起来更像这个
[Part Number] [Quantity1] [Price 1] [Quantity 2] [Price 2] [Quantity 3....
AAA-AAAA 100 1.23 200 1.15 ....
BBB-BBBB 100 5.60 ...
CCC-CCCC 500 3.21 ...
...
每个零件编号的所有条目组合成一行。第一个数量列应该具有最低可用数量,第二个应该具有第二个最小等等。我试图通过首先使用GROUP BY创建仅具有唯一部件号的1列表,然后为其创建更多表来实现此目的。每列在该列中包含我想要的信息,然后按部件号加入。计算每种类型的第二小数量时会出现问题,在倒数第二节中完成。
SELECT PNs.[Part Number], Q1T.Q1, P1T.Price, Q2T.Q2
FROM
(SELECT
[Part Number]
FROM FPB
GROUP BY [Part Number]
) AS PNs,
(SELECT
[Part Number],
MIN(Quantity) AS Q1
FROM FPB
GROUP BY [Part Number]
) AS Q1T,
(SELECT
*
FROM FPB
) AS P1T,
(SELECT
[Part Number],
MIN(IIF(Quantity>Q1T.Q1,Quantity)) AS Q2
FROM FPB
GROUP BY [Part Number]
) AS Q2T
WHERE
PNs.[Part Number] = Q1T.[Part Number]
AND P1T.[Part Number] = PNs.[Part Number]
AND P1T.Quantity = Q1T.Q1
AND Q2T.[Part Number] = PNs.[Part Number]
当我运行此查询时,它会要求我输入Q1T.Q1的参数值,即使它已经存在。如果我删除Q2T的代码部分以及对Q2的任何引用,它将没有问题,并且它不会询问Q1T.Q1的其他实例的值。为什么Q1T.Q1不具有该部分的值,我该如何解决?作为旁注,我正在使用名为PHPRunner的程序的SQL功能,其客户端不支持UPDATE / DELETE / INSERT / CREATE查询,UNION和DISTINCT。
答案 0 :(得分:1)
您调用的查询不正确。
Q1T是内部选择语句,而在Q2T(其他内部选择语句)中,您不能使用Q1T中的任何字段
SQL Server引发错误:')'附近的语法不正确。
要克服此限制,您应使用公用表格式CTE 对于PN,Q1T,P1T,Q2T
CTE就像动态视图。 它是自sql 2008以来的新功能,它非常强大。
评论:https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
尝试为这四个CTE绘制关系数据模型,以确保它们之间存在关系,具体取决于您的位置条件。 我认为此查询中的逻辑可能会在执行期间引发运行时错误:
e.g。多部分标识符" Q1T.Q1"无法受约束。
修改强>
对于 Ms-Access ,您可以创建四个查询:PN,Q1T,P1T,Q2T,每个查询都在一个单独的查询中,第五个查询加入这些查询并添加条件。 在这种情况下,您将不会收到任何语法错误。并且将获得数据模型与关系免费:)。
答案 1 :(得分:1)
你正在寻找这样的东西。
select
p1.PartNumber,
ifnull(max(p2.Quantity), 0) + 1 as LowerQuantity,
p1.Quantity as UpperQuantity,
p1.Price,
count(p2.PartNumber) + 1 as PriceTier
from
FPB p1 left outer join FPB p2
on p2.PartNumber = p1.PartNumber and p2.Quantity < p1.Quantity
从那里可以轻松转动以插入新表:
into into NewFPB (PartNumber, Quantity1, Price1, Quantity2, Price2, ...)
select
PartNumber,
min(switch(PriceTier = 1, UpperQuantity)) as Quantity1,
min(switch(PriceTier = 2, UpperQuantity)) as Quantity2, ...
min(switch(PriceTier = 1, Price)) as Price1,
min(switch(PriceTier = 2, Price)) as Price2, ...
from (
select
p1.PartNumber,
ifnull(max(p2.Quantity), 0) + 1 as LowerQuantity,
p1.Quantity as UpperQuantity,
p1.Price,
count(p2.PartNumber) + 1 as PriceTier
from
FPB p1 left outer join FPB p2
on p2.PartNumber = p1.PartNumber and p2.Quantity < p1.Quantity
) data
您可能需要稍微调整一下Access才能接受它。但核心思想就在那里。
答案 2 :(得分:0)
根据您的问题,在您定义派生表Q2T时,Q1T仍然是无效对象。您需要尝试解决此问题。
修改强>: 假设你只有2级列来处理,代码列在下面,我测试了它。效果很好。
select q5.*,q3.quantity, q3.price
from
(select *
from FPB as Q1
where 0 = (select count(distinct(quantity)) from FPB as Q2 where Q2.quantity < Q1.quantity AND Q2.[part number] = Q1.[part number])) as Q5
,
(
select distinct(temp.[part number]),Q2.quantity, Q2.price from FPB as temp
left join
(select *
from FPB as Q4
where 1 = (select count(distinct(quantity)) from #test as Q2 where Q2.quantity < Q4.quantity AND Q2.[PART NUMBER] = Q4.[PART NUMBER])) as Q2
on temp.[PART NUMBER] = Q2.[PART NUMBER]
) as Q3
where Q5.[PART NUMBER] = Q3.[PART NUMBER]