T-SQL - 子查询返回超过 1 个值
T-SQL - Subquery returned more than 1 value
有 2 个表:users
和 offers
。
我需要为每个用户提取 3 个优惠。
我写了这个命令行:
SELECT TOP 10
sellerID,
Country,
(SELECT TOP 3 ItemID
FROM Items i
JOIN Sellers s ON s.sellerID = i.UserID
ORDER BY CreatedDate)
FROM
Sellers
ORDER BY
Country desc
不确定是否真的 returns 我在找什么,但我得到这个错误:
Subquery returned more than 1 value.
This is not permitted when the subquery follows =, !=, <, <= , > >, >= or when the subquery is used as an expression.`
可以提出解决方案或解决方法吗?
您在 select 子句中有子查询。那里必须 return 1 行。尝试加入它-
SELECT
TOP 10 sellerID,
Country, items.ItemID
from Sellers
left join
(
SELECT TOP 3 UserID, ItemID
from Items i
join Sellers s
on s.sellerID=i.UserID
order by CreatedDate
) items
on sellers.UserID = items.UserID
order by Country desc
眼前的问题是您要求 select
输出每行包含 sellerId
、Country
和 three 的值的行ItemID
.
的值
子查询也与外部查询不相关,即您有对 Sellers
table 的第二个引用,但没有执行任何操作来将值与外部查询匹配。
假设您实际上想要最多 10 个国家/地区中每个国家/地区的前 3 项,这应该很接近:
-- Sample data.
declare @Sellers as Table ( SellerId Int, Country VarChar(16) );
insert into @Sellers ( SellerId, Country ) values
( 1, 'Canada' ), ( 2, 'Italy' ), ( 3, 'Elbonia' ), ( 4, 'Maldives' ), ( 5, 'Fiji' ),
( 6, 'Ecuador' ), ( 7, 'Chile' ), ( 8, 'Mexico' ), ( 9, 'Palau' ), ( 10, 'Yap' ),
( 11, 'Saba' );
declare @Items as Table ( ItemId Int, UserId Int, CreatedDate Date );
insert into @Items ( ItemId, UserId, CreatedDate ) values
( 1, 3, '20150308' ), ( 2, 3, '20150619' ), ( 3, 3, '20120908' ), ( 4, 3, '20140228' ),
( 2, 9, '20150308' ), ( 3, 9, '20150619' ), ( 4, 9, '20120908' ), ( 5, 9, '20140228' ),
( 3, 6, '20150308' ), ( 4, 6, '20150619' ), ( 4, 6, '20120908' ), ( 6, 6, '20140228' );
select * from @Sellers;
select * from @Items;
-- Show the intermediate results.
with AllSellersAndItems as
( select S.SellerId, S.Country, I.ItemId,
Row_Number() over ( partition by S.SellerId order by I.CreatedDate ) as ItemSequence,
Dense_Rank() over ( order by Country ) as SellerSequence
from @Sellers as S inner join
@Items as I on I.UserId = S.SellerId )
select * from AllSellersAndItems;
-- The real query.
with AllSellersAndItems as
( select S.SellerId, S.Country, I.ItemId,
Row_Number() over ( partition by S.SellerId order by I.CreatedDate ) as ItemSequence,
Dense_Rank() over ( order by Country ) as SellerSequence
from @Sellers as S inner join
@Items as I on I.UserId = S.SellerId )
select SellerId, Country, ItemId, SellerSequence, ItemSequence
from AllSellersAndItems
where SellerSequence <= 10 and ItemSequence <= 3
order by Country desc
此查询适合您:
SELECT TOP 10 sellerID, Country, items.ItemID
from Sellers
left join Items On Items.UserID = Sellers.sellerID
And Items.ItemID in ( Select Top 3 I_1.ItemID From Items As I_1
Where I_1.UserID = Sellers.sellerID
Order by CreatedDate )
ORDER BY Country desc
CROSS APPLY
就是您所需要的。请看查询示例:
SELECT TOP (10) S.SellerID, S.Country, I.ItemID
FROM dbo.Sellers AS S
CROSS APPLY (
SELECT TOP (3) I.ItemID
FROM dbo.Items AS I
WHERE S.SellerID = I.UserID
ORDER BY I.CreatedDate
) AS I
ORDER BY S.Country DESC;
此查询将为您返回 TOP (10)
结果。如果您想获得 TOP (10)
个用户和每个用户 3 个项目(这意味着最多 30 条记录),请改用此查询:
SELECT S.SellerID, S.Country, I.ItemID
FROM (
SELECT TOP (10) S.SellerID, S.Country
FROM dbo.Sellers AS S
ORDER BY S.Country DESC
) AS S
CROSS APPLY (
SELECT TOP (3) I.ItemID
FROM dbo.Items AS I
WHERE S.SellerID = I.UserID
ORDER BY I.CreatedDate
) AS I;
它的用途之一正是您所要求的。返回 TOP (n)
个子项。更多现实生活中的例子可以在这里找到:Real life example, when to use OUTER / CROSS APPLY in SQL
有 2 个表:users
和 offers
。
我需要为每个用户提取 3 个优惠。
我写了这个命令行:
SELECT TOP 10
sellerID,
Country,
(SELECT TOP 3 ItemID
FROM Items i
JOIN Sellers s ON s.sellerID = i.UserID
ORDER BY CreatedDate)
FROM
Sellers
ORDER BY
Country desc
不确定是否真的 returns 我在找什么,但我得到这个错误:
Subquery returned more than 1 value.
This is not permitted when the subquery follows =, !=, <, <= , > >, >= or when the subquery is used as an expression.`
可以提出解决方案或解决方法吗?
您在 select 子句中有子查询。那里必须 return 1 行。尝试加入它-
SELECT
TOP 10 sellerID,
Country, items.ItemID
from Sellers
left join
(
SELECT TOP 3 UserID, ItemID
from Items i
join Sellers s
on s.sellerID=i.UserID
order by CreatedDate
) items
on sellers.UserID = items.UserID
order by Country desc
眼前的问题是您要求 select
输出每行包含 sellerId
、Country
和 three 的值的行ItemID
.
子查询也与外部查询不相关,即您有对 Sellers
table 的第二个引用,但没有执行任何操作来将值与外部查询匹配。
假设您实际上想要最多 10 个国家/地区中每个国家/地区的前 3 项,这应该很接近:
-- Sample data.
declare @Sellers as Table ( SellerId Int, Country VarChar(16) );
insert into @Sellers ( SellerId, Country ) values
( 1, 'Canada' ), ( 2, 'Italy' ), ( 3, 'Elbonia' ), ( 4, 'Maldives' ), ( 5, 'Fiji' ),
( 6, 'Ecuador' ), ( 7, 'Chile' ), ( 8, 'Mexico' ), ( 9, 'Palau' ), ( 10, 'Yap' ),
( 11, 'Saba' );
declare @Items as Table ( ItemId Int, UserId Int, CreatedDate Date );
insert into @Items ( ItemId, UserId, CreatedDate ) values
( 1, 3, '20150308' ), ( 2, 3, '20150619' ), ( 3, 3, '20120908' ), ( 4, 3, '20140228' ),
( 2, 9, '20150308' ), ( 3, 9, '20150619' ), ( 4, 9, '20120908' ), ( 5, 9, '20140228' ),
( 3, 6, '20150308' ), ( 4, 6, '20150619' ), ( 4, 6, '20120908' ), ( 6, 6, '20140228' );
select * from @Sellers;
select * from @Items;
-- Show the intermediate results.
with AllSellersAndItems as
( select S.SellerId, S.Country, I.ItemId,
Row_Number() over ( partition by S.SellerId order by I.CreatedDate ) as ItemSequence,
Dense_Rank() over ( order by Country ) as SellerSequence
from @Sellers as S inner join
@Items as I on I.UserId = S.SellerId )
select * from AllSellersAndItems;
-- The real query.
with AllSellersAndItems as
( select S.SellerId, S.Country, I.ItemId,
Row_Number() over ( partition by S.SellerId order by I.CreatedDate ) as ItemSequence,
Dense_Rank() over ( order by Country ) as SellerSequence
from @Sellers as S inner join
@Items as I on I.UserId = S.SellerId )
select SellerId, Country, ItemId, SellerSequence, ItemSequence
from AllSellersAndItems
where SellerSequence <= 10 and ItemSequence <= 3
order by Country desc
此查询适合您:
SELECT TOP 10 sellerID, Country, items.ItemID
from Sellers
left join Items On Items.UserID = Sellers.sellerID
And Items.ItemID in ( Select Top 3 I_1.ItemID From Items As I_1
Where I_1.UserID = Sellers.sellerID
Order by CreatedDate )
ORDER BY Country desc
CROSS APPLY
就是您所需要的。请看查询示例:
SELECT TOP (10) S.SellerID, S.Country, I.ItemID
FROM dbo.Sellers AS S
CROSS APPLY (
SELECT TOP (3) I.ItemID
FROM dbo.Items AS I
WHERE S.SellerID = I.UserID
ORDER BY I.CreatedDate
) AS I
ORDER BY S.Country DESC;
此查询将为您返回 TOP (10)
结果。如果您想获得 TOP (10)
个用户和每个用户 3 个项目(这意味着最多 30 条记录),请改用此查询:
SELECT S.SellerID, S.Country, I.ItemID
FROM (
SELECT TOP (10) S.SellerID, S.Country
FROM dbo.Sellers AS S
ORDER BY S.Country DESC
) AS S
CROSS APPLY (
SELECT TOP (3) I.ItemID
FROM dbo.Items AS I
WHERE S.SellerID = I.UserID
ORDER BY I.CreatedDate
) AS I;
它的用途之一正是您所要求的。返回 TOP (n)
个子项。更多现实生活中的例子可以在这里找到:Real life example, when to use OUTER / CROSS APPLY in SQL