Question

Older questions seen

Table(s) Schema

Table entries having data from 2005-01-25

CREATE TABLE `entries` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `ctg` VARCHAR(15) NOT NULL,
    `msg` VARCHAR(200) NOT NULL,
    `nick` VARCHAR(30) NOT NULL,
    `date` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `msg` (`msg`),
    INDEX `date` (`date`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

Child table magnets with regular data from 2011-11-08(There might be a few entries from before that)

CREATE TABLE `magnets` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `eid` INT(10) UNSIGNED NOT NULL,
    `tth` CHAR(39) NOT NULL,
    `size` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
    `nick` VARCHAR(30) NOT NULL DEFAULT 'hjpotter92',
    `date` DATETIME NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `eid_tth` (`eid`, `tth`),
    INDEX `entriedID` (`eid`),
    INDEX `tth_size` (`tth`, `size`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

Question

I want to get the count of total number of entries by any particular nick(or user) entered in either of the table.

One of the entry in entries is populated at the same time as magnets and the subsequent entries of magnets can be from the same nick or different.

My Code

  • Try 1

    SELECT `e`.id, COUNT(1), `e`.nick, `m`.nick
    FROM `entries` `e`
    INNER JOIN `magnets` `m`
        ON `m`.`eid` = `e`.id
    GROUP BY `e`.nick
    
  • Try 2

    SELECT `e`.id, COUNT(1), `e`.nick
    FROM `entries` `e`
    GROUP BY `e`.nick
    UNION ALL
    SELECT `m`.eid, COUNT(1), `m`.nick
    FROM `magnets` `m`
    GROUP BY `m`.nick
    

The second try is generating some relevant outputs, but it contains double entries for all the nick which appear in both tables.

Also, I don't want to count twice, those entries/magnets which were inserted in the first query. Which is what the second UNION statement is doing. It takes in all the values from both tables.

SQL Fiddle link

Here is the link to a SQL Fiddle along with randomly populated entries.

I really hope someone can guide me through this. If it's any help, I will be using PHP for final display of data. So, my last resort would be to nest loops in PHP for the counting(which I am currently doing).

Desired output

The output that should be generated on the fiddle should be:

************************************************
**        Nick        |||        Count        **
************************************************
**        Nick1       |||         10          **
**        Nick2       |||          9          **
**        Nick3       |||          6          **
**        Nick4       |||         10          **
************************************************
Was it helpful?

Solution

There might be a more efficient way but this works if I understand correctly:

SELECT SUM(cnt), nick FROM
(SELECT count(*) cnt, e.nick FROM entries e 
  LEFT JOIN magnets m ON (e.id=m.eid AND e.nick=m.nick) 
  WHERE eid IS NULL GROUP BY e.nick
UNION ALL
  SELECT count(*) cnt, nick FROM magnets m GROUP BY nick) u 
GROUP BY nick
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top