数据库的相关部分如下所示(MS Visio,我知道我很可悲:D):
我需要提取一个列表,其中包含一个类别中的所有项目以及捆绑销售商品。因此,我必须使用UNION
。 UNION
的第一部分供您参考(因为它设置了SELECT
的第二部分中UNION
的数据格式;请注意,?
表示自变量进入的位置node-mysql
):
SELECT `ID`, `Name`, `Description`,
`PictureID`, `SellingPrice`,
`Cost`, 0 AS `Bundle`
FROM `Item`
WHERE `CategoryID`=? AND
`ID` IN (
SELECT `ItemID`
FROM `Stock`
WHERE `CityID`=?
AND `IsLimitless`=1 OR `Quantity`>0
)
所以我想将我的捆绑包也当作物品展示,并具有相同的字段等。
我的尝试:
SELECT `ID`, `Name`, `Description`, `PictureID`,
(
SELECT SUM( // Here SQL indicates a syntax problem
SELECT `ItemAmount`*`PriceModifier`*(
SELECT `SellingPrice`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
)
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`
)
) AS `SellingPrice`,
(
SELECT SUM(
SELECT `ItemAmount`*(
SELECT `Cost`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
)
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`
)
) AS `Cost`,
1 AS `Bundle`
FROM `Bundle`
WHERE `ID` IN (
SELECT `BundleID`
FROM `BundleCategory`
WHERE `CategoryID`=?
)
//No need to check bundles for stock due to business logic
我有一个微妙的想法,就是我对此过于复杂了,但是不幸的是,我不能为此动手。
任何建议都会非常欢迎,并在此先感谢您抽出宝贵的时间。 <3
样本数据:
Fields of no interest like "Description"/"PictureID"/"SupplierID" will be omitted
for the relevant parts to fit on screen
**Bundle**
ID Name Description PictureID
1 Valentine Pack Blah-blah tasty buy me imgur link in text
**Item**
ID Name SellingPrice Cost CategoryID
1 Movie Ticket 10 2 24
2 Box of Chocolates 5 1 4
3 Teddy Bear 15 3 2
4 Roses 10 4 8
**Stock**
ItemID CityID Quantity IsLimitLess
1 1 25 false
1 2 11 false
2 1 84 false
3 1 33 false
4 1 1 true
4 3 1 true
**BundleItem**
BundleID ItemID ItemAmount PriceModifier
1 1 2 1.25
1 2 1 1
1 3 1 1
1 4 5 0.75
**BundleCategory** (bundle for marketing reasons can appear in different
categories depending on its contents)
BundleID CategoryID
1 4 //Sweets
1 2 //Toys
1 8 //Flowers
所需输出:(用于搜索CityID 1,CategoryID 8,鲜花)
ID Name (Descr/PicID) SellingPrice Cost Bundle
4 Roses 10 4 false
1 Valentine Pack 82.5 28 true
/*2*10*1.25+ 2*2+ <movie
1*1*5+ 1*1+ <chocolate
1*1*15+ 3*1+ <teddy bear
5*0.75*10 5*4 <roses */
用户建议的解决方案 按照@ drakin8564的建议,我尝试做
SELECT `ID`, `Name`, `Description`, `PictureID`,
(
SELECT SUM((
SELECT `ItemAmount`*`PriceModifier`*(
SELECT `SellingPrice`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
)
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`
))
) AS `SellingPrice`,
(
SELECT SUM((
SELECT `ItemAmount`*(
SELECT `Cost`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
)
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`
))
) AS `Cost`,
1 AS `Bundle`
FROM `Bundle`
WHERE `ID` IN (
SELECT `BundleID`
FROM `BundleCategory`
WHERE `CategoryID`=8
)
返回
(1242): Subquery returns more than 1 row.
即使我尝试SELECT SUM((SELECT ID FROM Item))
,也会发生这种情况。奇怪的。
我对其他解决方案的效果进行了评论。感谢所有参与此活动的人。 <3
答案 0 :(得分:2)
您似乎遇到了一些语法问题。您的代码进行了一些更改。详情请参阅查询中的评论。
http://sqlfiddle.com/#!9/ee0725/16
SELECT `ID`, `Name`, `Description`, `PictureID`,
(SELECT SUM(`ItemAmount`*`PriceModifier`*( -- changed order of SELECT and SUM; removed extra SELECT; fixed Parens
SELECT `SellingPrice`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
))
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`)
AS `SellingPrice`,
(SELECT SUM(`ItemAmount`*( -- changed order of SELECT and SUM; removed extra SELECT; fixed Parens
SELECT `Cost`
FROM `Item`
WHERE `ID`=`BundleItem`.`ItemID`
))
FROM `BundleItem` WHERE `BundleID`=`Bundle`.`ID`)
AS `Cost`,
1 AS `Bundle`
FROM `Bundle`
WHERE `ID` IN (
SELECT `BundleID`
FROM `BundleCategory`
WHERE `CategoryID`=8
);
答案 1 :(得分:1)
类似的事情应该起作用
SELECT tb.`ID`, MAX(tb.`Name`), MAX(tb.`Description`), MAX(tb.`PictureID`),
SUM(`ItemAmount`*`PriceModifier`*`SellingPrice`) AS `SellingPrice`,
SUM(`ItemAmount`*`Cost`) AS `Cost`,
1 AS `Bundle`
FROM `Bundle` tb
JOIN `BundleItem` tbi on tb.ID=tbi.BundleID
JOIN `Item` ti on tbi.ItemID=ti.ID
WHERE tb.`ID` IN (
SELECT `BundleID`
FROM `BundleCategory`
WHERE `CategoryID`=?
)
GROUP BY tb.ID
//No need to check bundles for stock due to business logic
答案 2 :(得分:1)
您的语法错误是因为您的子查询未包含在()中。下面的示例。
这将失败:
SELECT SUM(SELECT 1);
这将起作用:
SELECT SUM((SELECT 1));
答案 3 :(得分:1)
假设1:一个城市中的所有物品都必须有足够的库存,以便该城市有可用的捆绑包。 (请参阅查询注释,了解如何删除此业务规则)
在样本数据中,任何城市都没有足够的捆绑商品-为了解决这个问题,我将CityID = 1中ItemID = 4的数量从“ 1”更改为“ 5”。这创建了您想要的输出。
假设2:允许库存。数量= 0。
此解决方案会生成查询结果,其中包含项目或捆绑包中有库存的每个城市和类别的所有项目和捆绑包。底部的where子句会根据原始请求将其过滤为CityID = 1和Category = 8。
注意:您可以将下面的“解决方案和架构”粘贴到www.sqlfiddle.com中并查看结果。
更新 固定的BundleCategory加入。
解决方案
select * from (
select
Stock.CityID,
Item.CategoryID,
Item.ID,
Item.Name,
Item.Description,
Item.SellingPrice,
Item.Cost,
'false' as Bundle
from Item
inner join Stock on Stock.ItemID = Item.ID
where IFNULL(Stock.Quantity,0) > 0 -- remove this to show out of stock items
union
select
BundleSummary.CityID,
BundleCategory.CategoryID,
Bundle.ID,
Bundle.Name,
Bundle.Description,
BundleSummary.SellingPrice as SellingPrice,
BundleSummary.Cost as Cost,
'true' as Bundle
from Bundle
inner join (
select
BundleItem.BundleID,
City.CityID,
MIN(IF(IFNULL(Stock.Quantity, 0) < BundleItem.ItemAmount, 0, 1)) as InStock,
SUM(Item.SellingPrice * BundleItem.ItemAmount * BundleItem.PriceModifier) as SellingPrice,
SUM(Item.Cost * BundleItem.ItemAmount) as Cost
from BundleItem
inner join Item on Item.ID = BundleItem.ItemID
inner join (select distinct CityID from Stock where CityID IS NOT NULL) as City on 1=1
left join Stock on Stock.ItemID = Item.ID and Stock.CityID = City.CityID
group by BundleItem.BundleID, City.CityID
) as BundleSummary on BundleSummary.BundleID = Bundle.ID
inner join BundleCategory on BundleCategory.BundleID = Bundle.ID
where BundleSummary.InStock = 1 -- remove this to show out of stock bundles
) as qry1
where CityID=1 and CategoryID=8;
我还生成了一个脚本来创建数据库模式,并用示例数据填充它。认为这可能对使用此解决方案来调查自己的问题的任何人有用。
架构
create table Item (
ID int,
Name varchar(255),
Description varchar(255),
PictureID int,
SellingPrice DECIMAL(12,4),
Cost DECIMAL(12,4),
SupplierID int,
CategoryID int
);
insert into Item values (1, 'Movie Ticket', '', NULL, 10, 2, NULL, 24);
insert into Item values (2, 'Box of Chocolates', '', NULL, 5, 1, NULL, 4);
insert into Item values (3, 'Teddy Bear', '', NULL, 15, 3, NULL, 2);
insert into Item values (4, 'Roses', '', NULL, 10, 4, NULL, 8);
create table Bundle (
ID int,
Name varchar(255),
Description varchar(255),
PictureID int
);
insert into Bundle values (1, 'Valentine Pack', 'Blah-blah tasty buy me', NULL);
create table Stock (
ItemID int,
CityID int,
Quantity int,
IsLimitless bit
);
insert into Stock values (1, 1, 25, false);
insert into Stock values (1, 2, 11, false);
insert into Stock values (2, 1, 84, false);
insert into Stock values (3, 1, 33, false);
insert into Stock values (4, 1, 5, true);
insert into Stock values (4, 3, 1, true);
create table BundleItem (
BundleID int,
ItemID int,
ItemAmount int,
PriceModifier DECIMAL(12,4)
);
insert into BundleItem values (1, 1, 2, 1.25);
insert into BundleItem values (1, 2, 1, 1);
insert into BundleItem values (1, 3, 1, 1);
insert into BundleItem values (1, 4, 5, 0.75);
create table BundleCategory (
BundleID int,
CategoryID int
);
insert into BundleCategory values (1, 4); -- Sweets
insert into BundleCategory values (1, 2); -- Toys
insert into BundleCategory values (1, 8); -- Flowers