我一直在考虑如何做这件事近两天,但仍无济于事。如果有人能给我指点或帮我做这个SQL语句,我会很感激。所以我有这些表......
Table1
NameField
Mark
John
Chris
Tina
Charles
Table2
NameField ItemField
Mark Pencil
Mark Bag
Mark Paper
Mark Book
John Book
John Ballpen
Chris Bag
Chris Paper
Chris Pencil
Tina Ballpen
Charles Computer
Charles Book
Charles Pencil
Charles Box
Charles Shoes
如何根据这些条件制作查询数据的SQL语句?
a)从NameField
Table1
ItemField
和Bag
以及Paper
获取所有Pencil
。
结果:
Chris
b)从NameField
获取所有Table1
,其中ItemField
Bag
和Paper
和Pencil
额外增加0或1或2随机ItemField
。
结果:
Mark, Chris
c)从NameField
Table1
ItemField
Pencil
获取所有ItemField
,无论Pencil
是否有其他项目,并计算额外项目(不包括项目{{ 1}})并列出额外的项目。
结果:
Mark - 3 - Bag, Paper, Book
Chris - 2 - Bag, Paper
Charles - 4 - Computer, Book, Box, Shoes
我尝试在服务器端脚本语言的帮助下执行此操作,循环遍历NameField
中的每个Table1
,然后再为每个ItemField
循环。所以如果我在Table
下有1000个项目,我需要循环1000个项目。解决方案效率低得离谱。所以我很抱歉,如果我到目前为止无法提供任何代码,因为我真的没有。什么都没有出现。这是我遇到的第一个这样的问题。非常感谢你。
答案 0 :(得分:2)
我只用表2给了它一个镜头。
1)
SELECT a.NameField,
COUNT(DISTINCT b.ItemField) AS MatchCount,
COUNT(DISTINCT a.ItemField) AS TotalCount,
GROUP_CONCAT(DISTINCT b.ItemField) AS MatchedItems,
GROUP_CONCAT(DISTINCT a.ItemField) AS AllItems
FROM Table2 a
LEFT JOIN Table2 b
ON b.NameField = a.NameField
AND b.ItemField IN ('Bag', 'Paper', 'Pencil')
GROUP BY a.NameField
HAVING TotalCount = 3 AND MatchCount = 3;
2)
SELECT a.NameField,
COUNT(DISTINCT b.ItemField) AS MatchCount,
COUNT(DISTINCT a.ItemField) AS TotalCount,
GROUP_CONCAT(DISTINCT b.ItemField) AS MatchedItems,
GROUP_CONCAT(DISTINCT a.ItemField) AS AllItems
FROM Table2 a
LEFT JOIN Table2 b
ON b.NameField = a.NameField
AND b.ItemField IN ('Bag', 'Paper', 'Pencil')
GROUP BY a.NameField
HAVING MatchCount >= 3;
3)
SELECT a.NameField,
COUNT(DISTINCT b.ItemField) AS OtherItemCount,
GROUP_CONCAT(DISTINCT b.ItemField) AS OtherItems
FROM Table2 a
LEFT JOIN Table2 b
ON b.NameField = a.NameField
AND b.ItemField != 'Pencil'
WHERE a.ItemField = 'Pencil'
GROUP BY a.NameField;
确实需要输入您匹配的项目数量,但希望它有所帮助!
修改:Here's a fiddle - would be fun to see this improved upon!
答案 1 :(得分:1)
查询A非常简单,所以我将从那开始:
SELECT Namefield FROM Table2
WHERE ItemField IN ('Bag', 'Paper', 'Pencil')
GROUP BY NameField
HAVING count(*) = 3;
查询B:在子查询中使用与上面相同的查询,但检查总项数是否小于或等于5(允许0,1,2额外)
SELECT Namefield FROM Table2
WHERE NameField IN
(SELECT Namefield FROM Table2 WHERE ItemField IN ('Bag', 'Paper', 'Pencil') GROUP BY NameField HAVING count(*) = 3)
GROUP BY NameField
HAVING count(*) <= 5;
查询C:我认为pssdbt的效果最好。请注意,包含多个这样的项目的东西应该由服务器端语言而不是SQL来处理。 SQL是数据的平面表示。
答案 2 :(得分:0)
我对其他人的看法略有不同,但它确实需要一些前期工作,其形式是使检查字符串按字母顺序排列。 我的查询的好处是它支持同一项的多次计数,例如获得3个铅笔和&amp; 2袋。
(受@pssdbt的回答启发)
查询A:
SELECT NameField, GROUP_CONCAT(ItemField ORDER BY ItemField) AS MatchedItems
FROM Table2
GROUP BY NameField
HAVING MatchedItems = "Bag,Paper,Pencil";
查询B:
SELECT NameField, GROUP_CONCAT(DISTINCT ItemField ORDER BY ItemField) AS MatchedItems ,
count(ItemField) as totalCount
FROM Table2
GROUP BY NameField
HAVING MatchedItems LIKE "%Bag%Paper%Pencil%" AND totalCount <= 5;
查询C:
SELECT NameField,
GROUP_CONCAT(DISTINCT if(ItemField="Pencil",null,ItemField) ORDER BY ItemField) AS MatchedItems,
SUM(if(ItemField="Pencil",0,1)) as extraCount,
SUM(if(ItemField="Pencil",1,0)) as hasPencil
FROM Table2
GROUP BY NameField
HAVING hasPencil > 0;