我很难编写选择,我可以为每个独特的行获得多个计数,我搜索整个网络并写入选择,但它不按我想要的方式工作。 所以,我有两个表横幅和bannerhistory
banners
Id UserId BannerName
167 35 Polly
168 35 Joke
169 21 Kim
170 35 Buck
................
BannerHistory
BannerId UserId IP
167 35 123asd123
167 35 123asd123
168 35 BBB123sss
.......................
So my query is:
SELECT
banners.Banner_Name,
banners.Counter,
banners.ClickCounter,
COUNT(DISTINCT(bannerhistory.Ip))
FROM
bannerhistory
INNER JOIN
banners
ON bannerhistory.BannerId = banners.ID
WHERE
bannerhistory.BannerId IN
(
SELECT
bannerhistory.BannerId
FROM
bannerhistory
WHERE
bannerhistory.UserId = $ UserId
)
GROUP BY
banners.Banner_Name
我想获取userId广告的所有bannerNames我想分别为每个横幅计算不同的IP-s。我的代码不工作因为计数得到第一个横幅不同(计数(Ip))每个横幅我的意思几乎总是数是相同的。任何人都可以帮助纠正我的查询?或者告诉我不同的方法。
不要担心计数器和clickcounter列,它们在banners
表中没有什么可以计算的,只是得到它们。
抱歉我的英文。
答案 0 :(得分:2)
尝试并使用以下查询:
Select b.Id,b.UserId,h.ips_count from banners b inner join
(select BannerId,count(distinct ip) as ips_count
from bannerhistory group by BannerId) h on b.Id = h.BannerId
注意/建议:强>
我认为在你的模式中,在bannerhistory中保留userId是多余的,以防横幅表本身具有id vs user的引用,
所以在bannerhistory中,应该只有bannerId vs ip组合。
答案 1 :(得分:1)
在这种情况下,您希望在子查询中执行聚合(COUNT ... GROUP BY)操作,然后执行连接。子查询看起来像这样,并获取历史记录表中每个用户和横幅ID组合的不同IP值的数量。 (http://sqlfiddle.com/#!9/c502bb/3/0)
SELECT BannerId, UserId, COUNT(DISTINCT IP) BannerCount
FROM bannerHistory
GROUP BY BannerId, UserId
然后,您可以将其作为虚拟表加入banner
表,然后使用WHERE
选择所需的用户ID。 (http://sqlfiddle.com/#!9/c502bb/2/0)
SELECT b.Id, B.UserId, b.BannerName, c.BannerCount
FROM banner B
JOIN (
SELECT BannerId, UserId, COUNT(DISTINCT IP) BannerCount
FROM bannerHistory
GROUP BY BannerId, UserId
) C ON B.Id = c.BannerId AND B.UserId = C.UserId
WHERE B.UserId = 35
请注意,MySQL查询规划器通常足够智能,即使在子查询中也能有效地处理WHERE
子句。
修改最后,普通的内部JOIN
会抑制与ON条件不匹配的行。要保留banner
表的每一行,您需要使用LEFT JOIN
。 (http://sqlfiddle.com/#!9/c502bb/4/0)
SELECT b.Id, B.UserId, b.BannerName, IFNULL(c.BannerCount, 0) BannerCount
FROM banner B
LEFT JOIN (
SELECT BannerId, UserId, COUNT(DISTINCT IP) BannerCount
FROM bannerHistory
GROUP BY BannerId, UserId
) C ON B.Id = c.BannerId AND B.UserId = C.UserId
WHERE B.UserId = 35
注意使用SELECT ... IFNULL
为BannerHistory
表中缺少的行添加零代替空值。
专业提示:制定缩进查询代码的个人风格,以便您可以在结构化查询语言中看到结构。缩进每个查询所需的额外30秒将在维护代码时自行回报数百次。