Query LEFT JOIN

Hi there, hope in your help.

I have this output generated by a query LEFT JOIN in my DB MySQL:

mysql> SELECT
	LCD,
	zonOp,
	Codex,
	Q,
	Codex2,
	NumberCode,
	CodeDates
FROM
	tbl_A A
LEFT JOIN tbl_CB CB ON A.Codex = Codex2
WHERE
 (
	Q > 0
	AND Codex2 IS NOT NULL
	AND NumberCode IS NOT NULL
	AND CodeDates NOT IN ('0000-00-00')
)
AND zonOp = 'RSID'
GROUP BY
	LCD,
	NumberCode;
+--------+-------+-------+-------+--------+------------+------------+
| LCD    | zonOp | Codex | Q     | Codex2 | NumberCode | CodeDates  |
+--------+-------+-------+-------+--------+------------+------------+
| RSIDP0 | RSID  | XM7   | 0,024 | XM7    |   51015524 | 2014-06-18 |
| RSIDP1 | RSID  | XM7   | 1,544 | XM7    |   47266370 | 2014-06-18 |
| RSIDP2 | RSID  | XM7   | 0,835 | XM7    |   48742114 | 2014-06-13 |
| RSIDP3 | RSID  | XI6   | 0,13  | XI6    |   29721250 | 2014-06-11 |
| RSIDP3 | RSID  | XM7   | 0,302 | XM7    |   29721253 | 2013-12-20 |
| RSIDP3 | RSID  | XM7   | 0,687 | XM7    |   38680929 | 2014-06-18 |
| RSIDP3 | RSID  | XM7   | 0,795 | XM7    |   39415749 | 2014-06-16 |
| RSIDP3 | RSID  | XG6   | 0,006 | XG6    |   40240767 | 2014-06-16 |
| RSIDP3 | RSID  | XI6   | 0,09  | XI6    |   40240769 | 2014-06-17 |
| RSIDP3 | RSID  | XM7   | 0,056 | XM7    |   40240770 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,504 | XM7    |   42624322 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,516 | XM7    |   42797920 | 2014-06-17 |
| RSIDP3 | RSID  | XM7   | 0,61  | XM7    |   45180544 | 2014-06-17 |
| RSIDP3 | RSID  | XM7   | 0,249 | XM7    |   45494706 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,252 | XM7    |   45541676 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,033 | XM7    |   46309158 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,303 | XM7    |   46348630 | 2014-06-25 |
| RSIDP3 | RSID  | XE5   | 0,068 | XE5    |   47542502 | 2014-06-17 |
| RSIDP3 | RSID  | XG6   | 0,07  | XG6    |   47542503 | 2014-06-17 |
| RSIDP3 | RSID  | XM7   | 0,231 | XM7    |   48541798 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,178 | XM7    |   50230398 | 2013-12-20 |
+--------+-------+-------+-------+--------+------------+------------+
21 rows in set

Now I need to extract a query LEFT JOIN in my DB MySQL this new output.
The criteria is that for each single value of the column LCD take at least 1 row up to 10 rows:


+------+-------+------------+
|N_LCD | LCD   | NumberCode |
+------+-------+------------+
|1     |RSIDP0 |51015524    |
|1     |RSIDP1 |47266370    |
|1     |RSIDP2 |48742114    |
|1     |RSIDP3 |29721250    |
|2     |RSIDP3 |29721253    |
|3     |RSIDP3 |38680929    |
|4     |RSIDP3 |39415749    |
|5     |RSIDP3 |40240767    |
|6     |RSIDP3 |40240769    |
|7     |RSIDP3 |40240770    |
|8     |RSIDP3 |42624322    |
|9     |RSIDP3 |42797920    |
|10    |RSIDP3 |45180544    |
+------+-------+------------+

And I tried this solution:

mysql> SELECT
	LCD,
	zonOp,
	Codex,
	Q,
	Codex2,
	NumberCode,
	CodeDates
FROM
	tbl_A A
LEFT JOIN tbl_CB CB ON A.Codex = Codex2
WHERE
 (
	Q > 0
	AND Codex2 IS NOT NULL
	AND NumberCode IS NOT NULL
	AND CodeDates NOT IN ('0000-00-00')
)
AND zonOp = 'RSID'
GROUP BY
	LCD,
	NumberCode
ORDER BY
	RAND()
LIMIT 10;
+--------+-------+-------+-------+--------+------------+------------+
| LCD    | zonOp | Codex | Q     | Codex2 | NumberCode | CodeDates  |
+--------+-------+-------+-------+--------+------------+------------+
| RSIDP3 | RSID  | XM7   | 0,231 | XM7    |   48541798 | 2014-06-16 |
| RSIDP3 | RSID  | XE5   | 0,068 | XE5    |   47542502 | 2014-06-17 |
| RSIDP3 | RSID  | XM7   | 0,795 | XM7    |   39415749 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,056 | XM7    |   40240770 | 2014-06-16 |
| RSIDP2 | RSID  | XM7   | 0,835 | XM7    |   48742114 | 2014-06-13 |
| RSIDP3 | RSID  | XM7   | 0,249 | XM7    |   45494706 | 2014-06-16 |
| RSIDP3 | RSID  | XI6   | 0,13  | XI6    |   29721250 | 2014-06-11 |
| RSIDP1 | RSID  | XM7   | 1,544 | XM7    |   47266370 | 2014-06-18 |
| RSIDP3 | RSID  | XM7   | 0,504 | XM7    |   42624322 | 2014-06-16 |
| RSIDP3 | RSID  | XM7   | 0,61  | XM7    |   45180544 | 2014-06-17 |
+--------+-------+-------+-------+--------+------------+------------+
10 rows in set

But the new output is wrong because for LCD value RSIDP0 I don’t have output and for LCD value RSIDP3 I have 8 and not 10 rows.

Any help would be appreciated, thank you in advance.

My tables MySQL below.



DROP TABLE IF EXISTS `tbl_A`;
CREATE TABLE `tbl_A` (
  `LCD` char(6) DEFAULT NULL,
  `NumberCode` int(11) DEFAULT NULL,
  `CodeDates` date DEFAULT NULL,
  `Codex` char(10) DEFAULT NULL,
  `Q` decimal(10,5) DEFAULT NULL,
  `zonOp` char(4) DEFAULT NULL,
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP0', 'RSID', 'XM7', 0.02400, 51015524, '2014-6-18');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP1', 'RSID', 'XM7', 1.54400, 47266370, '2014-6-18');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP2', 'RSID', 'XM7', 0.83500, 48742114, '2014-6-13');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XI6', 0.13000, 29721250, '2014-6-11');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.30200, 29721253, '2013-12-20');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.68700, 38680929, '2014-6-18');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.79500, 39415749, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XG6', 0.00600, 40240767, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XI6', 0.09000, 40240769, '2014-6-17');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.05600, 40240770, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.50400, 42624322, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.51600, 42797920, '2014-6-17');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.61000, 45180544, '2014-6-17');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.24900, 45494706, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.25200, 45541676, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.03300, 46309158, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.30300, 46348630, '2014-6-25');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XE5', 0.06800, 47542502, '2014-6-17');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XG6', 0.07000, 47542503, '2014-6-17');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.23100, 48541798, '2014-6-16');
INSERT INTO `tbl_A` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.17800, 50230398, '2013-12-20');



DROP TABLE IF EXISTS `tbl_cb`;
CREATE TABLE `tbl_cb` (
  `Codex2` varchar(3) NOT NULL,
  PRIMARY KEY (`Codex2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `tbl_cb` VALUES ('XE5');
INSERT INTO `tbl_cb` VALUES ('XG6');
INSERT INTO `tbl_cb` VALUES ('XI6');
INSERT INTO `tbl_cb` VALUES ('XM7');
INSERT INTO `tbl_cb` VALUES ('XQ7');

The reason you’re getting what you are is the LIMIT 10 is for the entire recordset, not by the grouping.

BTW, mySQL must be much more forgiving - I’ve never been able to get GROUP BY to work with a limited grouping of fields like that…

Thank you, but without LIMIT 10 I’ve the wrong output … 21 rows instead of 13 rows …

oh, man, you don’t know the half of it

this “feature” of mysql’s GROUP BY actually makes sense (for those who can understand why it works) but in my opinion it has caused exponentially more grief than any good it’s done

see Debunking GROUP BY myths

because of this condition, you get inner join results only, so you might as well write INNER JOIN instead

as for your “max 10 per group” i think i can help you with that, but you have to have a condition to select which 10 – and it cannot be random

But what I’m saying is LIMIT is not applied as an addition to the GROUP BY process. In your example, it pulls the full result set you had in your original query (though see Rudy’s post regarding the join type - it’s faster), applies the RAND() to order it, then takes the first 10 rows of that order.

Ugh…I can (kinda) see why they made it work like that, but from a purely maintenance standpoint, I would hate it as it’s not specific, and easy to miss…

thank you, I have tried this, but the set is empty:

mysql> SELECT
	*
FROM
	(
		SELECT
			a.LCD,
			(SELECT 1 + count(*) FROM tbl_a b) RANK
		FROM
			tbl_A A
		LEFT JOIN tbl_CB CB ON A.Codex = Codex2
		WHERE
			(
				Q > 0
				AND Codex2 IS NOT NULL
				AND NumberCode IS NOT NULL
				AND CodeDates NOT IN ('0000-00-00')
			)
		AND zonOp = 'RSID'
		GROUP BY
			LCD,
			NumberCode
	) AS x
WHERE
	x.RANK BETWEEN 1
AND 10;
Empty set

mysql> 

well, of course

obviously, tbl_a has more than 10 rows

If the ORDER BY and LIMIT clauses where left out how many rows would you expect to get in a result set on the live site?

I’am sorry not understand your question.

I have tried this solution but the output this is, what’s wrong?:


mysql> SELECT
	t1.id,
	t1.LCD,
	count(*) AS earlier
FROM
	tbl_a AS t1
JOIN tbl_a AS t2 ON t1.LCD = t2.LCD
AND t1.LCD >= t2.LCD
LEFT JOIN tbl_CB CB ON t1.Codex = cb.Codex2
WHERE
	(
		t1.Q > 0
		AND CB.Codex2 IS NOT NULL
		AND t1.NumberCode IS NOT NULL
		AND t1.CodeDates NOT IN ('0000-00-00')
	)
AND t1.zonOp = 'RSID'
GROUP BY
	t1.LCD,
	t1.NumberCode
HAVING
	earlier <= 10;
+------+--------+---------+
| id   | LCD    | earlier |
+------+--------+---------+
| 6263 | RSIDP0 |       1 |
| 6264 | RSIDP1 |       1 |
| 6265 | RSIDP2 |       1 |
+------+--------+---------+
3 rows in set

mysql> 

it’s getting harder and harder to figure out what you’re actually trying to do

now you’re joining tbl_a to itself… why?

the join condition makes no sense –

 ON t1.LCD = t2.LCD
AND t1.LCD >= t2.LCD

also, i think you missed my comment that you should be using INNER JOIN instead of LEFT JOIN

as for your “max 10 per group” i think i can help you with that, but you have to have a condition to select which 10 – and it cannot be random

I see thanks… this solution working and the output is correct … I would like comments and opinions about this work…

mysql&gt; DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `LCD` char(6) DEFAULT NULL,
  `NumberCode` int(11) DEFAULT NULL,
  `CodeDates` date DEFAULT NULL,
  `Codex` char(10) DEFAULT NULL,
  `Q` decimal(10,5) DEFAULT NULL,
  `zonOp` char(4) DEFAULT NULL,
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP0', 'RSID', 'XM7', 0.02400, 51015524, '2014-6-18');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP1', 'RSID', 'XM7', 1.54400, 47266370, '2014-6-18');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP2', 'RSID', 'XM7', 0.83500, 48742114, '2014-6-13');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XI6', 0.13000, 29721250, '2014-6-11');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.30200, 29721253, '2013-12-20');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.68700, 38680929, '2014-6-18');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.79500, 39415749, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XG6', 0.00600, 40240767, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XI6', 0.09000, 40240769, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.05600, 40240770, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.50400, 42624322, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.51600, 42797920, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.61000, 45180544, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.24900, 45494706, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.25200, 45541676, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.03300, 46309158, '2014-6-16');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XM7', 0.30300, 46348630, '2014-6-25');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP3', 'RSID', 'XE5', 0.06800, 47542502, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP5', 'RSID', '123', 0.06800, 47542502, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP6', 'RSID', '123', 0.06800, 47542502, '2014-6-17');
INSERT INTO `test` (`LCD`, `zonOp`, `Codex`, `Q`, `NumberCode`, `CodeDates`) VALUES ('RSIDP7', 'RSID', 'XXX', 0.06800, 47542502, '2014-6-17');

SELECT
	tmp.LCD,
	tmp.NUMBERCODE,
	tmp.codex, 
        tmp.rank
FROM
	(
		SELECT
			LCD,
			NUMBERCODE,
			codex,

		IF (
			@prev &lt;&gt; LCD,
			@rownum := 1,
			@rownum := @rownum + 1
		) AS rank,
		@prev := LCD
	FROM
		test t 
	JOIN (
		SELECT
			@rownum := NULL,
			@prev := 0
	) AS r
	WHERE
		(
			Q &gt; 0 
      AND Codex IS NOT NULL
			AND NumberCode IS NOT NULL
			AND CodeDates NOT IN ('0000-00-00')
		)
	AND zonOp = 'RSID'
	) AS tmp
INNER JOIN tbl_CB CB ON tmp.Codex = cb.Codex2
WHERE
	tmp.rank &lt;= 10
GROUP BY
	LCD,
	NumberCode
ORDER BY
	LCD,
	NUMBERCODE;
Query OK, 0 rows affected

Query OK, 0 rows affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

Query OK, 1 row affected

+--------+------------+-------+------+
| LCD    | NUMBERCODE | codex | rank |
+--------+------------+-------+------+
| RSIDP0 |   51015524 | XM7   |    1 |
| RSIDP1 |   47266370 | XM7   |    1 |
| RSIDP2 |   48742114 | XM7   |    1 |
| RSIDP3 |   29721250 | XI6   |    1 |
| RSIDP3 |   29721253 | XM7   |    2 |
| RSIDP3 |   38680929 | XM7   |    3 |
| RSIDP3 |   39415749 | XM7   |    4 |
| RSIDP3 |   40240767 | XG6   |    5 |
| RSIDP3 |   40240769 | XI6   |    6 |
| RSIDP3 |   40240770 | XM7   |    7 |
| RSIDP3 |   42624322 | XM7   |    8 |
| RSIDP3 |   42797920 | XM7   |    9 |
| RSIDP3 |   45180544 | XM7   |   10 |
+--------+------------+-------+------+
13 rows in set

mysql&gt;  

impressive… most impressive… but you are not a jedi yet

Does the table called “tbl_cb” actually have more fields in it or is there only the field “Codex2” in it?

In the table called “tbl_cb” is there only the field “Codex2”