我有这个问题:
SELECT C.ID_PASS, C.ID_MERCE, CTRL.ESITO, M.ID_CAT, M.QTA, M.DESCRIZ,
CTRL.ID_PUNTO, CTRL.ID_ADDETTO, C.DATE_OPEN, C.DATE_CLOSE, C.NOTE
FROM CONTESTAZIONI C, CONTROLLI CTRL, FUNZIONARI F, ADDETTI A, MERCI M
WHERE A.ID=CTRL.ID_ADDETTO
AND A.ID_FUNZ=501
AND M.ID=C.ID_MERCE
AND M.ID_PASS=C.ID_PASS
AND CTRL.ESITO > 1
GROUP BY C.ID_PASS;
为什么,如果我不添加GROUP BY C.ID_PASS
,我会得到20行(而不是2行)。
答案 0 :(得分:1)
使用“,”运算符进行连接时会得到一个交叉产品。您应该将所有表中的ID包含在where子句中!
基本上,您需要通过确保其行的ID的相等性来将所有5个表链接在一起,因为如注释中所述,您有两组表,但它们没有链接,因此结果集具有大量重复项。
答案 1 :(得分:1)
GROUP BY用于在使用聚合函数(例如SUM或COUNT。)时将行组合在一起。
例如,如果您有4条记录,每条帐户名称为2条,则每条记录都有一个值: -
CustId Spend
1 10
1 20
2 30
2 40
如果您想知道每个客户的每个值的总和,您可以使用以下内容: -
SELECT CustId, SUM(Spend) FROM SomeTable GROUP BY CustId
这会给你
CustId Sum(Spend)
1 30
2 70
它的部分功能是删除重复的行并将所有值汇总到一行。
如果没有聚合函数可以滥用它来删除重复项,这就是你所做的。因此有2条记录而不是20条。
请注意,如果SELECT中的字段不在GROUP BY变量中,并且不是100%依赖于group by字段,那么该字段的值是不确定的。
例如
CustId Spend ShopId
1 10 1
1 20 2
2 30 3
2 40 4
如果您想知道每个客户的每个值的总和,您可以使用以下内容: -
SELECT CustId,ShopId,SUM(支出)FROM SomeTable GROUP BY CustId
这会给你
CustId Sum(Spend) ShopId
1 30 Could be 1 or could be 2
2 70 Could be 3 or could be 4
在您的查询中,这可能适用于字段CTRL.ESITO,M.ID_CAT,M.QTA,M.DESCRIZ, CTRL.ID_PUNTO,CTRL.ID_ADDETTO。
答案 2 :(得分:1)
您正在对表进行隐式交叉连接。尝试使用不同类型的Join,例如Inner,Right或Left。
示例:
SELECT *
FROM CONTESTAZIONI c
INNER JOIN CONTROLLI ctrl ON c.ID = ctrl.ContId
答案 3 :(得分:1)
现代(意思是1992年后)明确的JOIN符号的一个优点是你不太可能忘记加入条件。你有5张桌子;你需要(至少)4个加入条件。您的SQL只有2个连接条件(其中一个是复合连接)。您没有给我们足够的架构以确保提供正确的加入列,但您的查询可能应该是这样的:
SELECT C.ID_PASS, C.ID_MERCE, CTRL.ESITO, M.ID_CAT, M.QTA, M.DESCRIZ,
L.ID_PUNTO, L.ID_ADDETTO, C.DATE_OPEN, C.DATE_CLOSE, C.NOTE
FROM ADDETTI A
JOIN CONTROLLI L ON A.ID = L.ID_Addetto
JOIN CONTESTAZIONI C ON A.xxx1 = C.xxx2
JOIN FUNZIONARI F ON C.yyy1 = F.yyy2
JOIN MERCI M ON M.ID = C.ID_Merce AND M.ID_Pass = C.ID_Pass
WHERE A.ID_FUNZ=501
AND L.ESITO > 1;
请注意,您显示了A和L(从CTRL重命名),M和C的连接.C到A和F到C的连接是半任意猜测(列名xxx1
等等是你真实列名的占位符);您将需要了解您的架构并进行适当的连接。
答案 4 :(得分:0)
感谢大家。现在我明白了:我必须将我选择的所有表格加在一起(当然只有关系中的表格);没有这个加入我得到一个交叉产品。我可以加入" JOIN ...... ON ..."或者"在哪里......"。我和WHERE加入了。现在工作正常:
SELECT C.ID_PASS, C.ID_PUNTO, C.ID_ADDETTO, C.TIME_START,
C.TIME_END, C.ESITO, P.ID_NAZ, C.ID_MERCE, M.QTA, M.DESCRIZ, M.ID_CAT
FROM CONTROLLI C, PASSEGGERI P, MERCI M, FUNZIONARI F, CATEGORIE, ADDETTI, NAZIONI
WHERE
ADDETTI.ID=C.ID_ADDETTO
AND P.ID=M.ID_PASS
AND P.ID_NAZ=NAZIONI.ID
AND M.ID_PASS=C.ID_PASS AND M.ID=C.ID_MERCE -- composite PK (so another AND reuqired)
AND M.ID_CAT=CATEGORIE.ID
AND F.ID=ADDETTI.ID_FUNZ
AND ESITO > 1
AND F.ID = 501