我想从三个表中获取信息,如:
项目
itemId Name Quantity Price
1 Pen 100 1,0
2 Pencil 100 0,5
3 Glue 20 1,5
ItemFiles
itemId fileId
1 1001
1 1002
1 1003
2 2001
3 3001
3 3002
phisicsFile
fileId Filename
1001 order_101_20170621.pdf
1002 delivery_404_20170627.pdf
1003 payement_20170630.pdf
2001 order_102_20170623.pdf
3001 order_103_20170624.pdf
3002 delivery_404_20170627.pdf
我需要一个像这样的结果的单一查询
Name Quantity Price Order Delivery Payed
Pen 100 1,0 True True True
或
Pencil 100 0,5 True False False
或
Glue 20 1,5 True True False
我尝试这样的事情
SELECT
I.itemId AS Id,
CASE
WHEN FS.Filename like '%'Order'%' THEN 'True'
ELSE 'False'
END AS Order
FROM Item I
left join
ItemFiles on I.itemId = IF.itemId
left join phisicsFile PF on (IF.file_id = PF.fileId AND PF.Filename like '%order%')
WHERE I.itemId= @itemId
但是我在结果中得到重复的行
答案 0 :(得分:2)
您不需要LEFT JOIN
,只需加入GROUP BY
即可。然后使用条件计数来检查每种文件类型的存在。
<强> SQL DEMO 强>
SELECT I.[itemId], I.[Name], I.[Quantity], I.[Price],
CAST( COUNT(CASE WHEN P.Filename like '%order%' THEN 1 END) as bit) as [Orders],
CAST( COUNT(CASE WHEN P.Filename like '%delivery%' THEN 1 END) as bit) as [Delivery],
CAST( COUNT(CASE WHEN P.Filename like '%payement%' THEN 1 END) as bit) as [Payment]
FROM Items I
JOIN ItemFiles F
ON I.[itemId] = F.[itemId]
JOIN phisicsFile P
ON F.[fileId] = P.[fileId]
GROUP BY I.[itemId], I.[Name], I.[Quantity], I.[Price]
<强>输出强>
答案 1 :(得分:1)
这是另一种选择......
IF OBJECT_ID('tempdb..#Item', 'U') IS NOT NULL
DROP TABLE #Item;
CREATE TABLE #Item (
ItemId INT NOT NULL PRIMARY KEY CLUSTERED,
Name VARCHAR(20) NOT NULL,
Quantity INT NOT NULL,
Price MONEY NOT NULL
);
INSERT #Item (ItemId, Name, Quantity, Price) VALUES
(1, 'Pen', 100, 1.0),
(2, 'Pencil', 100, 0.5),
(3, 'Glue', 20, 1.5);
IF OBJECT_ID('tempdb..#ItemFiles', 'U') IS NOT NULL
DROP TABLE #ItemFiles;
CREATE TABLE #ItemFiles (
ItemId INT NOT NULL,
FileId INT NOT NULL,
PRIMARY KEY CLUSTERED (ItemId, FileId)
);
INSERT #ItemFiles (ItemId, FileId) VALUES
(1, 1001),
(1, 1002),
(1, 1003),
(2, 2001),
(3, 3001),
(3, 3002);
IF OBJECT_ID('tempdb..#PhisicsFile', 'U') IS NOT NULL
DROP TABLE #PhisicsFile;
CREATE TABLE #PhisicsFile (
FieldId INT NOT NULL PRIMARY KEY CLUSTERED,
FileName VARCHAR(50) NOT NULL
);
INSERT #PhisicsFile (FieldId, FileName) VALUES
(1001, 'order_101_20170621.pdf'),
(1002, 'delivery_404_20170627.pdf'),
(1003, 'payement_20170630.pdf'),
(2001, 'order_102_20170623.pdf'),
(3001, 'order_103_20170624.pdf'),
(3002, 'delivery_404_20170627.pdf');
--=================================================
SELECT
i.ItemId,
i.Name,
i.Quantity,
i.Price,
[Order] = CASE WHEN xif.HasOrder = 1 THEN 'True' ELSE 'False' END,
Delivery = CASE WHEN xif.HasDelivery = 1 THEN 'True' ELSE 'False' END,
Payement = CASE WHEN xif.HasPayement = 1 THEN 'True' ELSE 'False'END
FROM
#Item i
OUTER APPLY (
SELECT
HasOrder = MAX(CASE WHEN pf.FileName LIKE 'order%' THEN 1 END),
HasDelivery = MAX(CASE WHEN pf.FileName LIKE 'delivery%' THEN 1 END),
HasPayement = MAX(CASE WHEN pf.FileName LIKE 'payement%' THEN 1 END)
FROM
#ItemFiles ifi
JOIN #PhisicsFile pf
ON ifi.FileId = pf.FieldId
WHERE
i.ItemId = ifi.ItemId
) xif;
HTH, 杰森
答案 2 :(得分:0)
select Id,Name,Quantity,Price,
case when [order] = 1 then 'true' else 'false' end as [order],
case when [delivery]=1 then 'true' else 'false' end as [delivery],
case when [payement]=1 then 'true' else 'false' end as [payement]
from
(SELECT
I.itemId AS Id,
I.Name,
I.Quantity,
I.Price,
SUBSTRING(PF.Filename,0,charindex('_',PF.Filename)) stat
FROM #Item I
INNER join #ItemFiles Itf on I.itemId = Itf.itemId
INNER join #phisicsFile PF on Itf.fileId = PF.fileId) as s
PIVOT
(
count(stat) for stat IN ([order],[delivery],[payement])
) as p
如果您使用的是sql 2016,则可以使用STRING_SPLIT(字符串,分隔符)代替子字符串。
答案 3 :(得分:0)
onCreate()